Enis
Enis

Reputation: 95

Angular: multiple material snackbar in global ErrorHandler

I use in angular the following global ErrorHandler:

@Injectable()
export class GlobalErrorHandler implements ErrorHandler {

  constructor(private errorService: ErrorService, private messageNotificationService: MessageNotificationService) { }

  handleError(error: Error | HttpErrorResponse | any) {
      // handle api server error
    }
    else {
      // client Error
      message = this.errorService.getClientErrorMessage(error);
      this.messageNotificationService.showError(message);
    }
  }
}

and the following NotificationService with snackbar

@Injectable({
  providedIn: 'root'
})
export class MessageNotificationService {

  constructor(
    public snackBar: MatSnackBar,
    private zone: NgZone) { }

  showError(message: string): void {
    this.zone.run(() => {
      this.snackBar.open(message, 'X', { panelClass: ['error'], verticalPosition: "top", horizontalPosition: "center" });
    });
  }
}

when an angular client error/exception occurs in loops, then several snackbars are displayed overlapping:

enter image description here

Is there a way to reduce the snackbar showing to 1 time? Is there a way to stop the error/exception propagation?

Upvotes: 1

Views: 2432

Answers (1)

YogendraR
YogendraR

Reputation: 2396

You can maintain a count variable, and do something like this:

@Injectable({
  providedIn: 'root'
})
export class MessageNotificationService {

 count = 0;
 snackBarRef;

 constructor(public snackBar: MatSnackBar,
          private zone: NgZone) {
 }

 showError(message: string): void {

   this.count++;

   if (this.count === 1) {
      this.zone.run(() => {
        this.snackBarRef = this.snackBar.open(message, 'X', {
        panelClass: ['error'],
        verticalPosition: "top",
        horizontalPosition: "center"
       });
     });
   }

  this.snackBarRef.afterDismissed().subscribe(() => {
   this.count = 0;
  });

  }
}

Upvotes: 0

Related Questions