question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. ItΒ collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

AsyncPipe subscribe in NgZone

See original GitHub issue

🐞 bug report

Affected Package

The issue is caused by package @angular/common

Is this a regression?

Yes, the previous version in which this bug was not present was: ....

No

Description

AsyncPipe subscribe in NgZone, will cause useless change detection.

πŸ”¬ Minimal Reproduction

see: https://github.com/xiaoxiangmoe/angular-async-inner-check/blob/master/src/app/child-view/child-view.component.ts#L7

If we change <div> a = {{ a$ | asyncInnerCheck }} </div> to <div> a = {{ a$ | async }} </div>, ngAfterViewChecked for ChildViewComponent and AppComponent will be triggered.

If we are in a giant angular app, a small async pipe binding will cause the Change Detection of the entire app to be triggered.

🌍 Your Environment

Angular Version:

Angular CLI: 9.0.7
Node: 13.5.0
OS: darwin x64

Angular: 9.0.7
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router
Ivy Workspace: Yes

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.900.7
@angular-devkit/build-angular     0.900.7
@angular-devkit/build-optimizer   0.900.7
@angular-devkit/build-webpack     0.900.7
@angular-devkit/core              9.0.7
@angular-devkit/schematics        9.0.7
@ngtools/webpack                  9.0.7
@schematics/angular               9.0.7
@schematics/update                0.900.7
rxjs                              6.5.4
typescript                        3.7.5
webpack                           4.41.2

Anything else relevant?

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:11
  • Comments:17 (11 by maintainers)

github_iconTop GitHub Comments

4reactions
petebacondarwincommented, Jun 8, 2020

We discussed this in the team meeting today.

It is felt that changing the behaviour of this pipe like this would undoubtedly break a number a projects, since it is quite likely that some projects rely upon the CD cycle that is triggered by the async pipe subscribing to an observable.

Moreover, it is felt that there is no single approach to the async pipe that will satisfy all the potential use cases in this regard; and it is very hard to determine what is the best choice for any one scenario.

So this would result in the async pipe having to be configurable; and for developers to find it difficult to decide which to use.

It was pointed out that an alternative solution would be to be able to isolate a single component so that only its change detection is triggered for a particular dirty mark. There is a design in process to modify how change detection works so that it should be possible to achieve this: https://docs.google.com/document/d/1ciKBdPnEzOLruX2kHeITCScMlv6JEj0WxLSnIb_0LoQ. Please do take a look at this design and comment.

In the meantime, the workaround is to write a custom pipe that subscribes outside of the NgZone. I have updated my Stackblitz example to avoid relying upon any private APIs: https://stackblitz.com/edit/ivy-n5q9ix?file=src%2Fapp%2Fcustom-async.pipe.ts

I will leave this issue open for now since we hope to solve the problem via the design mentioned above.

3reactions
sodcommented, Mar 20, 2020

Maybe too late for an existing app as you may rely heavily on global change detection. But when we rebuilt our website we started with setting the root component to OnPush. This disables all the default change detection and will only check components during a tick, that you explicitly markForCheck (which the async pipe automatically does). So with that pattern, the async pipe will indeed only update the source template - plus every child templates where inputs change.

We could do that as we also switched to ngrx, so all the state is propagated via observables and the async pipes take care of telling angular what to update.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Use async pipe for polling Observables? - angular
All code is executed within the ngZone and protractor will wait for all ... I cannot use the async pipe, I have to...
Read more >
Angular zone and async pipe : r/Angular2 - Reddit
Async pipe does not have anything to do [directly] with NgZone. The pipe subscribes to an observable and marks the view as dirty...
Read more >
Running async events outside Angular with runOutsideAngular
In this recipe, you'll learn how to execute code blocks outside of the ngZone service, ... Continue reading with a subscription.
Read more >
Angular async pipe does not work in the electron
The simplest solution to this problem is to add ngZone.run inside on handler this.scanner.on('scannerDevices', (devices) => {...}) WorkingΒ ...
Read more >
When to use the subscribe method or async pipe in Angular?
Predominately there are two ways to read observable data,. Using the async pipe; By subscribing to the observable using the subscribe() method.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found