Search code examples
angularservice

An notification doesn't display without window click


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)
     }
   }
 }


}


Solution

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