Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular (4): Custom Error Handler & DI: Cannot instantiate cyclic dependency

I'm trying to inject an Angular Material 2 element into a custom error handler I wrote, but I keep getting this error:

Cannot instantiate cyclic dependency! ApplicationRef ("[ERROR ->]"): in NgModule AppModule in ./AppModule@-1:-1

This is the error handler class:

@Injectable()
export class CustomErrorHandler implements ErrorHandler {

  constructor(private snackBar: MdSnackBar) {
  }

  handleError(error: any): void {
    //FIXME: display popup
    console.error('Error occurred!');
    console.error(error);
    this.snackBar.open('Application Error: ' + error, 'X', {
      duration: environment.snackBarTime,
    });
  }

}

This is the providers part of app.module

providers: [
    SearchService,
    CompanyService,
    MdSnackBar,
    PopupService,
    AuthService,
    LoginService,
    AuthGuard,
    ErrorService,
    TokenStorageService,
    BankService,
    CountryService,
    {provide: ErrorHandler, useClass: CustomErrorHandler},
    {provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true},
  ],
  exports: [
    TranslateModule
  ],
  bootstrap: [AppComponent]
})
like image 649
Deniss M. Avatar asked Sep 04 '17 11:09

Deniss M.


1 Answers

We have to manually call the injector with the service name in the execution of the handleError function.

So I had to use the built in Inject to inject my service dependency. The end result of the custom-error-handler class which calls the PopupService which has the MdSnackBar dependency injected looks like this:

@Injectable()
export class CustomErrorHandler implements ErrorHandler {

  constructor(private injector: Injector) {
  }

  handleError(error: any): void {
    console.log(error);
    const popupService = this.injector.get(PopupService);   
  }

}

And this is the PopupService:

@Injectable()
export class PopupService {

  constructor(private snackBar: MdSnackBar) {
  }

  public throwErrorPopup(textOfError: string) {
    this.snackBar.open(textOfError, 'X', {
      duration: environment.snackBarTime,
    });
  }

}

Solution mentioned in here: https://medium.com/@amcdnl/global-error-handling-with-angular2-6b992bdfb59c

like image 140
Deniss M. Avatar answered Oct 05 '22 23:10

Deniss M.