AsyncPipe subscribe in NgZone
See original GitHub issueπ bug report
Affected Package
The issue is caused by package @angular/commonIs 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
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:
- Created 4 years ago
- Reactions:11
- Comments:17 (11 by maintainers)
Top 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 >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
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.
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 explicitlymarkForCheck
(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.