I have an Angular app containing an HttpInterceptor and an ErrorHandler. Errors intercepted by the HttpInterceptor are then handled by the ErrorHandler. The ErrorHandler pushes error messages onto a Subject, to which AppComponent is subscribed.
In this way I am hoping to display HTTP errors in the view of AppComponent.
The general approach seems to work, because I receive error messages in AppComponent when I call
Actually the GET call fails because of browser policies, which is fine. Any error will do to demonstrate the real problem:
In AppComponent I can console.log()
the error message, but the message isn't bound to the view. errorMessage
is still "none"
:
Stackblitz example: https://stackblitz.com/edit/angular-ivy-zikova?file=src/app/app.component.ts
CodePudding user response:
The handleError()
is called outside of the Angular Zone so the change detection will not detect any changes inside the component. You can use the run()
method from NgZone
to avoid the problem.
Inject the NgZone
into the GlobalErrorHandlerService
and call the next()
inside the run
method.
constructor(private zone: NgZone) { }
handleError(error: any) {
this.zone.run(() => {
this.subject.next(error.message);
});
}
Another option would be to use OnPush
change detection in your AppComponent
. Set the changeDetection
to ChangeDetectionStrategy.OnPush
and inject the ChangeDetectorRef
. Inside the subscriber call the detectChanges()
method to detect the changes.
constructor(
private service: Service,
private errorHandlerService: GlobalErrorHandlerService,
private changeDetectorRef: ChangeDetectorRef
) {
this.errorHandlerService.subject.subscribe((message) => {
console.log('Error in AppComponent: ' message);
this.errorMessage = message;
this.changeDetectorRef.detectChanges();
});
this.service.getNonExistentUrl().subscribe(() => console.log('bla'));
}