Home > Software engineering >  Angular string variable not bound to template
Angular string variable not bound to template

Time:11-05

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 enter image description here

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":

enter image description here

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'));
}
  • Related