Angular Customized SnackBar Service


Description

This is a customized SnackBar Service that can be used to show snackbar in angular using material with different styles like error, info, success, warn, normal.

// snack-bar.service.ts
import { Injectable, NgZone, inject } from '@angular/core';
import { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';

export enum SnackStyle {
  ERROR = 'error',
  INFO = 'info',
  SUCCESS = 'success',
  WARN = 'warn',
  NORMAL = 'normal',
}

const defaultOptions = {
  action: 'Close',
  style: SnackStyle.NORMAL,
  duration: 3000,
  horizontalPosition: 'center',
  verticalPosition: 'top',
};

const panelClasses = {
  error: 'red-500',
  info: 'blue-grey-500',
  success: 'green-500',
  warn: 'yellow-500',
  normal: '',
};

@Injectable()
export class SnackBarService {
  #snackBar = inject(MatSnackBar);
  #ngZone = inject(NgZone);

  public normal(message: string, action?: string, options?: MatSnackBarConfig) {
    this.open(message, action, { ...options, style: SnackStyle.NORMAL });
  }

  public warn(message: string, action?: string, options?: MatSnackBarConfig) {
    this.open(message, action, { ...options, style: SnackStyle.WARN });
  }

  public info(message: string, action?: string, options?: MatSnackBarConfig) {
    this.open(message, action, { ...options, style: SnackStyle.INFO });
  }

  public error(message: string, action?: string, options?: MatSnackBarConfig) {
    this.open(message, action, { ...options, style: SnackStyle.ERROR });
  }

  public success(
    message: string,
    action?: string,
    options?: MatSnackBarConfig
  ) {
    this.open(message, action, { ...options, style: SnackStyle.SUCCESS });
  }

  public open(
    message: string,
    action?: string,
    options?: {
      style?: SnackStyle;
    } & MatSnackBarConfig<any>
  ) {
    const opts: { style?: SnackStyle } & MatSnackBarConfig<any> = {
      ...defaultOptions,
      ...options,
    } as any;
    const { style, ...conf } = opts;
    conf.panelClass = style ? panelClasses[style] : '';
    this.show(message, undefined, conf);
  }

  private show(
    message: string,
    action: string | undefined,
    configuration: MatSnackBarConfig
  ) {
    this.#ngZone.run(() =>
      this.#snackBar.open(message, undefined, configuration)
    );
  }
}

Styling

For styling the snackbar, you have to override the following css variables. in global styles.scss file.

.mat-mdc-snack-bar-container {
  --mdc-snackbar-container-color: inherit;
  --mdc-snackbar-supporting-text-color: inherit;
}

Usage

import { Component, OnInit } from '@angular/core';
import { AlertModalService } from './alert-modal.service';

@Component({
  selector: 'test-page',
  standalone: true,
  imports: [CommonModule],
  template: `<button (click)="remove(id)">Delete</button> `,
})
export class TestComponent implements OnInit {
  #snackBarService = inject(SnackBarService);

  async remove(id: number) {
    this.#snackBarService.success('Deleted Successfully');
  }
}