Igor Simic
4 years ago

Angular Material - display multiple Snackbars messages in sequence


How to display multiple snackbar messages using material design? Material design snack-bar are great and simple way to show notifications to the users. In this tutorial we will explain and show how to change color, position and list multiple snack-bars.

In this example we will use:
  1. Material design
  2. Material design snackbars
  3. Angular Material 100% content height
  4. Material Theme - more about you can find here or here

OK, so first we will install material design and  then add needed modules, open the app.module.ts and add these lines:
// needed for snackbar
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { MatButtonModule } from '@angular/material/button';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

@NgModule({
  imports:      [ 
    ...
    MatSnackBarModule,
    MatButtonModule,
    BrowserAnimationsModule,
    ...
],
  
})
export class AppModule { }

Now, we will create Snackbar component which will be in charge for firing snackbar messages. Create folder Components and inside create snackbar.component.ts and paste this code:
import { Component, OnInit } from '@angular/core';
import { MatSnackBar } from '@angular/material/snack-bar';

@Component({
  selector: 'app-snackbar',
  templateUrl: './snackbar.component.html',
  styleUrls: ['./snackbar.component.css']
})

export class SnackbarComponent implements OnInit {

  timeOut = 1500;

  constructor(
    public snackBar: MatSnackBar
  ) { }


  openSnackBar(message, action: string, className: string) {

    if ( message instanceof Array) {

        message.forEach( (message, index) => {

            setTimeout(() => {
              
                this.snackBar.open(message.text, action, {
                    duration: this.timeOut,
                    verticalPosition: 'bottom', // 'top' | 'bottom'
                    horizontalPosition: 'end', //'start' | 'center' | 'end' | 'left' | 'right'
                    panelClass: [className],
                });
                

            }, index * (this.timeOut+500)); // 500 => timeout between two messages

        });


    } else {

      this.snackBar.open(message.text, action, {
        duration: this.timeOut,
        verticalPosition: 'bottom', // 'top' | 'bottom'
        horizontalPosition: 'end', //'start' | 'center' | 'end' | 'left' | 'right'
        panelClass: [className],
      });

    }


  }


}

Here we have included material design snackbar module and defined function openSnackBar() which can be called from other components and it will fire our snackbar notification messages. It will accept 3 params in our case:
  1. messages - array of messages
  2. action - send the text for close button
  3. className - color of snackbar

In our method, we will first check is the message array of messages or a single string. To check that we will use  instanceOf array and then loop through messages if it is array, or just show single snackbar message if it is not array.

How to set angular material snackbar position

In our case we are placing the position of material snackbar to bottom of the page by setting values for verticalPosition and horizontalPosition params, but it can be placed to couple more different positions:
verticalPosition: 'bottom', // 'top' | 'bottom'
horizontalPosition: 'end', //'start' | 'center' | 'end' | 'left' | 'right'

Let's create our message list and try to trigger this method. Open app.components.ts (or any other component) from where you want to trigger snackbar and these lines:
import { Component } from '@angular/core';
import { SnackbarComponent } from './Components/snackbar.component';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})

export class AppComponent {

   // list of messages
   messages = [
      {
        text: "This is message 1",
      },
      {
        text: "This is message 2",
      }
   
  ];

  constructor(
    public snackbar: SnackbarComponent,
  ) { }

  showSnackbar(color){
    
    this.snackbar.openSnackBar(this.messages, 'Close',color);


  }
}
Here we have included our SnackBarComponent, and we hardcoded two messages in our message array. And we created function which can be called by click on the button. In your case, maybe you will have to call it when you get response from your server or some other way... But in our case we will trigger the snackbar messages by clicking on a button. Open app.component.html and add our button:
  • <button mat-button color="primary" (click)="showSnackbar('red-snackbar')">Show red snackbar</button>
By calling the showSnackbar() function we are sending the class name where we defined the background and text color for our snackbar. These are two simple css definitions which i have places in style.scss
.red-snackbar{
  background-color: rgb(153, 50, 50);
  color:lightgoldenrodyellow;
}
  

.green-snackbar{
  background-color: rgb(29, 102, 29);
  color:lightgreen;
}
Now we can change the color of snack-bar by calling showSnackbar() with different class names:
  • showSnackbar('green-snackbar') - for green snack-bar
  • showSnackbar('red-snackbar') - for red snack-bar 
  • showSnackbar() - if we do  not send param, angular will use default background color defined by theme (in our case is black)

And that would be it, working version you can double check on StackBlitz by going to:
https://stackblitz.com/edit/angular-e4xwxh