I have created a test case to reproduce the issue I am seeing based on Routing Angular documentation and the live demo found therein.
The live demo was slightly modified so that browser desktop notifications are requested and a simple notification is shown in app.component.ts
[browser notification code was pasted from somewhere].
Please take note of the notification's onclick
handler below. It merely logs to console and navigates to one of app's original routes.
notification.onclick = function () {
console.log('onclick');
self.router.navigate(['/heroes']);
};
To reproduce the problem make sure to Open in New Window and allow the app to show desktop notifications when prompted. A notification will be shown immediately after giving permissions. Upon clicking the notification you will notice that the router navigates to the new URL but nothing gets rendered. The console output shows 'onclick' as expected but no ngOnInit()
. The heroes.component.ts
was also modified to output ngOnInit()
as shown below, but this never happens. If you were to click the Heroes
button, the ngOnInit()
would have worked as expected.
ngOnInit() {
console.log('ngOnInit');
this.getHeroes();
}
After a bit of debugging it turns out that the router navigates as expected, heroes
component gets instantiated (as the constructor gets called) but the ngOnInit()
never executes.
It appears as if the onclick
context of the browser desktop notification somehow screws up Angular's internals. Is this what really happens? Is this some sort of Angular bug?
I have also tried using ng-push but the same behavior is observed.
In my own full-blown app there is one slight difference in behavior. The ngOnInit()
does get called eventually but it takes up to 10 seconds after component's constructor executes. The browser seems to sit idle consuming no CPU during the wait period.
I am baffled. Any ideas? How come routing works normally when a button is clicked yet it demonstrates this strange behavior when used from a click handler of a browser's desktop notification?
Please note I have tested in latest Chrome (67.0.3396.87), Firefox (60.0.2) and Edge (all on Windows 10 with latest updates).
I'm not sure why, but the method is ran outside the Angular Zone. That is why the url is changing but Angular doesn't detect it so ngOnInit
is not called. Note that it run when you click the clear message button for example. You can simply fix it by running it in zone:
notification.onclick = () => {
this.zone.run(() => {
console.log('onclick');
this.router.navigate(['/heroes']);
});
};
constructor(private router: Router, private zone: NgZone) {
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With