Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I am using Angular 7 and facing an issue => after login the API GET calls successfully and the component receiving data too, but UI is not displaying that data.

When I open the browser console, immediately the data gets populated on the UI and a warning is showing in the console.

"core.js:15686 Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?"

I have googled this warning and found some workaround like this.ngZone.run() and call my API's inside it.

But the issue is, I am using more than 40 components and calling so many API in each component. So I have to call ngZone.run() on each API call, which seems to be difficult to do.

Please suggest me the better approach to overcome this issue. Thanks in advance.

app.component.ts

getEmployees(): void {
    this.employeeService.getEmployees().subscribe(e => {
        this.employees = e;
    });
}

app.service.ts

@Injectable()
export class EmployeeService {
    constructor(private httpClient: HttpClient) { }

    getEmployees() {
        return this.httpClient.get<EmployeeModel[]>('employees');
    }
like image 369
Er Vipin Sharma Avatar asked Dec 06 '18 06:12

Er Vipin Sharma


People also ask

What is NgZone run?

In those cases, the NgZone service provides a run() method that allows you to execute a function inside the Angular zone. This function, and all asynchronous operations in that function, trigger change detection automatically at the correct time.

Do you still think that NgZone zone JS is required for change detection in angular?

Yes, Zone and NgZone is used to automatically trigger change detection as a result of async operations.

What would be a good use for NgZone service in angular?

Angular 2 runs inside of its own special zone called NgZone and this special zone extends the basic functionality of a zone to facilitate change detection. It is Running inside a zone allows to detect when asynchronous tasks.


2 Answers

Usually this happens when you are wrapping angular calls inside some external js callback, from external JavaScript not related to angular code.

Example app.component.ts:

callMyCustomJsLibrary() {
  googleSdk.getLocations(location => this.getEmployees());
}

getEmployees(): void {
    this.employeeService.getEmployees().subscribe(e => {
        this.employees = e;
    });
}

In this case you will have to include the call into the NgZone, example: this.ngZone.run(() => this.getEmployees());

The app.component.ts would then look like the following:

callMyCustomJsLibrary() {
  googleSdk.getLocations(location => this.ngZone.run(() => this.getEmployees()));
}

getEmployees(): void {
    this.employeeService.getEmployees().subscribe(e => {
        this.employees = e;
    });
}
like image 74
albanx Avatar answered Oct 24 '22 09:10

albanx


My issue fixed by wrapping the router navigation command in ngZone. Please check the code below

in constructor add "private zone: NgZone".

private zone: NgZone

this.zone.run(() => {
                    this.router.navigate(['/login']);
                });
like image 35
Shakoor Hussain Attari Avatar answered Oct 24 '22 09:10

Shakoor Hussain Attari