AgGrid Cell Component agInit runs sometimes outside of the zone
Andrew Henderson
Issue
We use a Angular cell component which contains a button. I noticed that sometimes (approximately 1 out of 10 times) the button event is handled outside of the zone which leads to issues.
What I've found out so far
agInit sometimes runs outside of the zone. I found that out by using the following snippet:
agInit(params: RendererParams): void { const inZone = NgZone.isInAngularZone(); console.log("AgInit in Zone?: " + inZone);
}If agInit is not in the angular zone, the button callback is also not in the zone.
I also noticed that the callstack is slightly different in the case where agInit runs inside our outside the zone:
Here is a link to a full diff of both stack traces:
I also noticed that in the error case, the callstack start from Utils.debounce in agGrid.
To further investigate the issue, I forked the ngzone (see snippet below). No errors were logged.
ngDoBootstrap(applicationRef: ApplicationRef) { const debugSpec: ZoneSpec = { name: "debugSpec", onHandleError: (parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, error: any) => { console.log(error); return true; } }; Zone.current.fork(debugSpec).run(() => { applicationRef.bootstrap(AppComponent); });
}Workaround
I can always manually run the callback within the zone. That works.
51 Answer
I found the the problem. Since it's hard to reproduce I am not 100% sure though. I think it is a AgGrid bug.
Why?
- I noticed that if it is outside the zone its called by Utils.debounce
- Then i check where ag grid calls it. In around 6 places. One of them was in a ResizeObserver callback
- Angular zone monkeypatches setTimeout, but not ResizeObserver
- I could toggle between ResizeObserver and and polyfill which relies on setTimeout by using
suppressBrowserResizeObserverin the gridSettings - I wrote an automation to refresh the browser in an endless loop and stop when the error happens
- I could always with max 10 refresh reproduce the error with ResizeObserver enabled
- I could never reproduce the error using the polyfill
Will open an issue on github.
How i fixed the issue
I added the following import:
import ' 5