Please consider the following code:
//our root app component
import {ChangeDetectionStrategy, Component, ErrorHandler, Injector, NgModule, ViewContainerRef} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import {BrowserAnimationsModule} from "@angular/platform-browser/animations";
import {ToastModule, ToastsManager} from "ng2-toastr/ng2-toastr";
@Component({
selector: 'my-app',
template: `
<div>
name={{(test$|async).name}}
</div>
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class App {
test$: Observable<{name:string}> = null;
constructor(toastr: ToastsManager, viewContainerRef: ViewContainerRef) {
toastr.setRootViewContainerRef(viewContainerRef);
}
}
export class CustomErrorHandler extends ErrorHandler {
constructor(private injector: Injector) { super(); }
handleError(err: any): void {
super.handleError(err);
this.injector.get(ToastsManager).error(err.message);
}
}
@NgModule({
imports: [ BrowserModule, BrowserAnimationsModule, ToastModule.forRoot() ],
declarations: [ App ],
bootstrap: [ App ],
providers: [
{ provide: ErrorHandler, useClass: CustomErrorHandler, deps: [Injector] }
]
})
export class AppModule {}
Also available as a Plunker here.
An error is intentionally triggered in the component template (test
is undefined). The custom error handler kicks in, logs the error and tries to pop up an error toast. Not only doesn't the toast pop up, but also the application keeps logging over and over the original error. Digging a little seems to indicate that this is caused by the toaster's setTimeout function being called repeatedly. I have tried doing something similar with different toaster libraries but with the same result.
The expected behaviour is that the toast pop ups once and that the error is logged only once.
Any idea on how to achieve this?
Throw the error at the end of handleError()
.
Source: https://github.com/scttcper/ngx-toastr/issues/564#issuecomment-419910273
This isn't an issue with ngx-toastr.
What is happening is that if there's something like a template error and you've "handled" the error, change detection will continue to run over and over causing the infinite loop. You need to throw an error at the end of the function.
However, since unhandled http errors (and other smaller errors that could be easily handled) will also throw the error at the end and will cause change detection to stop running. The trick is to only throw an error at the end when it's something that you cannot handle or that should cause change detection to stop running (like template errors)
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