Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot Inject ToastrService into a custom error handler. #179

Closed
countzyx opened this issue Aug 29, 2017 · 7 comments
Closed

Cannot Inject ToastrService into a custom error handler. #179

countzyx opened this issue Aug 29, 2017 · 7 comments

Comments

@countzyx
Copy link

countzyx commented Aug 29, 2017

Running the latest version of ngx-toastr with Angular 4.1.2. I'm trying to make a custom error handler that puts out toasts when unexpected errors happen. The code looks like this -

`
import { ToastrService } from 'ngx-toastr';
import { ErrorHandler, Inject } from "@angular/core";

export class AppErrorHandler implements ErrorHandler {
constructor(@Inject(ToastrService) private toastrService:ToastrService) { }

handleError(error: any): void {
    this.toastrService.error(
        "An unexpected error has occurred.",
        "Error",
        {
          closeButton: true,
          timeOut: 5000
        }
      )
}

}
`

When I try this I get an error on the console about there being a cyclic dependency while processing the app.module file.
Error: Provider parse errors: Cannot instantiate cyclic dependency! ApplicationRef ("[ERROR ->]"): in NgModule AppModule in ./AppModule@-1:-1

I suspect that this error is misleading and Angular is just having trouble linking dependencies since the error handler gets loaded pretty early in the startup cycle. Is the problem even fixable? Or is there a way to feed error messages into a queue that can be processed by a service that once loaded can emit toasts? Any help is greatly appreciated.

@trevor-hackett
Copy link
Collaborator

Try something like what I mentioned in this post

Maybe we need to add this to the FAQ or add an example into the repo

@trevor-hackett
Copy link
Collaborator

trevor-hackett commented Aug 29, 2017

Your example would be something like the following:

import { ErrorHandler, Inject, Injector, Injectable } from "@angular/core";
import { ToastrService } from "ngx-toastr";

@Injectable()
export class AppErrorHandler extends ErrorHandler {

  constructor(@Inject(Injector) private injector: Injector) { 
    super(true);
  }

  // Need to get ToastrService from injector rather than constructor injection to avoid cyclic dependency error
  private get toastrService(): ToastrService {
    return this.injector.get(ToastrService);
  }

  public handleError(error: any): void {
    this.toastrService.error(
      "An unexpected error has occurred.",
      "Error",
      {
        closeButton: true,
        timeOut: 5000,
        onActivateTick: true
      }
    );

    super.handleError(error);
  }
}

Then in AppModule:

@NgModule({
  // Your imports, declarations, bootstrap, etc.
  // ...

  providers: [
    // Other providers...

    {
      provide: ErrorHandler,
      useClass: AppErrorHandler
    }
  ]
})
export class AppModule {}

@crhistianramirez
Copy link

You might also need to turn on onActivateTick in the error handler to ensure that the toast is running inside Angular's zone.

An updated example can be found here - #327

@trevor-hackett
Copy link
Collaborator

Updated the example here since this is where the FAQ points to.

@zymr-keshav
Copy link

thank you for this nice snippet here is my issue
see the complete issue here : https://stackoverflow.com/questions/49148781/custom-error-handler-throw-error-cannot-read-property-get-of-undefined-inj

@trevor-hackett
Copy link
Collaborator

trevor-hackett commented Mar 7, 2018

What you're trying to do in that issue on stackoverflow is not the same as what is mentioned here. This issue is about trying to inject ToastrService into a custom ErrorHandler. In that SO issue, you're trying to access ToastrService from a custom error. This is not the same and isn't possible unless you pass the ToastrService into the constructor of your AccessDenied class. new AccessDenied(toastrService)

I've posted an answer on SO.

@Alsmith141510
Copy link

I am using angular 7.3.3, angular material and ngrx-toastr. I have a login screen which is a matdialog. On error I want show a toastr with error. but I am getting an error. Any pointer would be helpful.

Repository owner locked as resolved and limited conversation to collaborators Mar 6, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants