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');
}
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.
Yes, Zone and NgZone is used to automatically trigger change detection as a result of async operations.
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.
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;
});
}
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']);
});
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