I made GlobalHandlerError service. Errors good display in console, however when i added angular-notifier- notifications display only after mouse click in current window(for every notification need one click even if we have some notification together). I tried test angular-notifier in typical component- all well work, but in my service - don't work. Even if i use that without forEach loop.
import {ErrorHandler, Injectable} from '@angular/core';
import {HttpErrorResponse} from "@angular/common/http";
import {NotifierService} from "angular-notifier";
import {ResponseFromServer} from "../entity/ResponseFromServer";
@Injectable({
providedIn: 'root'
})
export class GlobalErrorHandlerService implements ErrorHandler{
errorOnClientSide:Error|undefined
private readonly notifier: NotifierService
responseFromServer:ResponseFromServer|undefined
constructor( notifierService:NotifierService) {
this.notifier = notifierService;
}
handleError(error: any): void {
if (error instanceof HttpErrorResponse){
this.responseFromServer=error.error
if (error.ok){
this.notifier.notify('success',"Success!")
console.log("success")
console.log(this.responseFromServer)
} else {
console.log("error from server")
this.responseFromServer?.errors?.forEach(err=> this.notifier.notify('error',err.toString()))
console.log("GONE!")
}
} else {
if (error instanceof Error) {
this.errorOnClientSide=error
this.notifier.notify('error',this.errorOnClientSide.message)
console.error("Error on client-side " error)
} else {
console.error("Unknown error:" error)
}
}
}
}
CodePudding user response:
I've seen it happen before that if a call is being triggered by something other than an HttpClient
method, then it doesn't properly trigger change detection in the subscriber/error handler. You could see if this is the issue by manually triggering change detection using zone.run
:
import { ErrorHandler, Injectable, NgZone } from '@angular/core';
import { HttpErrorResponse } from "@angular/common/http";
import { NotifierService } from "angular-notifier";
import { ResponseFromServer } from "../entity/ResponseFromServer";
@Injectable({
providedIn: 'root'
})
export class GlobalErrorHandlerService implements ErrorHandler {
errorOnClientSide: Error | undefined
private readonly notifier: NotifierService
responseFromServer: ResponseFromServer | undefined
constructor(notifierService: NotifierService, private zone: NgZone) {
this.notifier = notifierService;
}
handleError(error: any): void {
this.zone.run(() => {
if (error instanceof HttpErrorResponse) {
this.responseFromServer = error.error
if (error.ok) {
this.notifier.notify('success', "Success!")
console.log("success")
console.log(this.responseFromServer)
} else {
console.log("error from server")
this.responseFromServer?.errors?.forEach(err => this.notifier.notify('error', err.toString()))
console.log("GONE!")
}
} else {
if (error instanceof Error) {
this.errorOnClientSide = error
this.notifier.notify('error', this.errorOnClientSide.message)
console.error("Error on client-side " error)
} else {
console.error("Unknown error:" error)
}
}
});
}
}
CodePudding user response:
I recently had a similar issue and eventually resolved it by wrapping the notify()
-call in a timeout. I.e. I now make the call asynchronously:
setTimeout(() =>{
this.notifier.notify('error', 'Test-Message');
}, 0);
Explanation:
If the call to this.notifier.notify()
is made synchronously, it might be executed before Angular's change detection has a chance to run, which could cause the notification to be missed.