When to use Ngzone.run()?

dasfdsa picture dasfdsa · Jul 21, 2018 · Viewed 45.2k times · Source

I got a bug in my angular project which finally resolved by wrapping my code into

this.zone.run(() => {/* my code here */});

as stated by this answer.

My previous understanding of zone was that angular can't detect changes made by async callbacks of third-party libraries because "they are not in angular's zone". If I click on a button, the event that gets triggered is not browser's native click event but a custom (patched) click event created by angular whose handler runs in the zone so angular is aware of the changes made by its callback handler.

But I could not understand by running router.navigate() in third party callback create this problem (as indicated by this github issue). Isn't Router a service of angular itself? Why doesn't it automatically inform angular's zone when called in third party callback?

I got this problem by using router.navigate within state reducer of NGXS.

My question is:

Can someone explain when exactly do I need to wrap my code in NgZone?

Debugging for hours and realizing that my code is out of zone context is tiresome.

Answer

Darshan Bhavsar picture Darshan Bhavsar · Oct 9, 2019

ngZone.runOutsideAngular() - this runs the code outside the angular zone.

  • When some event is fired it tells angular to detect changes.
  • If you are using mouseUp() or mouseDown() event, then on every change it tells angular to detect the changes.
  • If we don't want these changes to take place run-time in angular (which reduces performance of the app), we can run it outside of angular zone.
  • Contrast to this, if we keenly want to get each and every update then we can use ngZone.run(). Means it will run the change detection in normal.

Angular itself uses ngZone under the hood to detect the changes

So, if we have came out of angular zone, then to come back we use ngZone.run()