Kezz
Kezz

Reputation: 193

'Navigation triggered outside Angular zone' explanation

I am working on an Electron app using Angular. I have created an Electron menu item where click() sends an IPC to app.component.ts in order to change the view. The below code works, but I get the following error in DevTools if I call router.navigateByUrl directly:

Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?

As you can see, I now call router.navigateByUrl through ngZone, solving the problem, but despite reading about NgZone in the docs and searching here and elsewhere, I don't understand what this does or why I need to do it.

  1. What's wrong with calling this.router.navigateByUrl directly?

  2. Why does it tell me the call is outside the Angular zone, when it is called within app.component.ts?

Electron main.js

function sendToAngularRouter(request)
{
    console.log('sending request');
    win.webContents.send('routeToPage', request);
}

Angular app.component.ts

export class AppComponent implements OnInit {

    constructor(public electronService: ElectronService, 
         private router: Router, private zone: NgZone) {}

    ngOnInit() {
        this.electronService.ipcRenderer.on('routeToPage', (sender, arg) => {
          this.navigateTo(arg);
        });
    }

    navigateTo(arg: string): void {
        this.zone.run(() => {
            this.router.navigateByUrl(`/${arg}`);
        });
    }
}

Thank you in advance.

Upvotes: 17

Views: 9707

Answers (1)

As the documentation says:

A zone provides an execution context that persists across async tasks

The navigation is an async task, and angular needs to detect the change across electron to render your new View, so the angular zone, defines what is running into the angular execution context, and what is running outside, in this case electron

Upvotes: 1

Related Questions