Angular2: Custom toaster / notification service using Angular2 Material Snackbar Component

Standard

Since toasters/notifications are essential component for any connected web application, we have couple of toasters component available in market for angular2, I am using Angular Material Snackbar component.

Usage

Since toasters/notifications are used throughout the application, so its better to define as unified service and then consume it throughout application by injecting service in various controllers.

Pre-Step:

  • Install Angular Material components
npm install --save @angular/material
  • Import the Angular Material NgModule in src/app/app.module.ts
import { MaterialModule } from '@angular/material';
// other imports 
@NgModule({
  imports: [MaterialModule],
  ...
})
export class PizzaPartyAppModule { }
  • Some of the components like md-slide-toggle, md-slider, mdTooltip rely on HammerJS for gestures
npm install --save hammerjs

After installing, import HammerJS on your app’s module. src/app/app.module.ts

import 'hammerjs';
  • If your project is using SystemJS for module loading, you will need to add @angular/material to the SystemJS configuration:
System.config({
  // existing configuration options
  map: {
    ...,
    '@angular/material': 'npm:@angular/material/bundles/material.umd.js'
  }
});

Reference

Step 1 : Create angular material toaster service IN toaster.service.ts:

import { Injectable } from '@angular/core';
import { MdSnackBar } from '@angular/material';

@Injectable()
export class ToasterService {

    constructor(private snackBar: MdSnackBar) {
    }

    showToaster(msg: string) {
        this.snackBar.open(msg, null, {
            duration: 3000,
        });
    }
}

A snack-bar can contain either a string message or a given component.

// Simple message.
let snackBarRef = snackBar.open('Message archived');

// Simple message with an action.
let snackBarRef = snackBar.open('Message archived', 'Undo');

// Load the given component into the snack-bar.
let snackBarRef = snackbar.openFromComponent(MessageArchivedComponent);

Step 2: Register toaster service to main module IN app.module.ts:

import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { MaterialModule } from '@angular/material';
import 'node_modules/hammerjs/hammer.js';

import { AppComponent } from './app.component';
import { CustomComponent } from './custom.component';
import { ToasterService } from './shared/service/toaster.service';

@NgModule({
    imports: [
        //angular builtin module
        BrowserModule,

        //ui module
        MaterialModule.forRoot()
    ],
    declarations: [
        AppComponent,
        CustomComponent 
    ],
    providers: [
        ToasterService
    ],
    bootstrap: [
        AppComponent
    ],
    schemas: [
        CUSTOM_ELEMENTS_SCHEMA
    ]
})

export class AppModule {
}

Step 3: Inject toaster service in controller, let say custom.component.ts:

import { Component, OnInit } from '@angular/core';
import { ToasterService } from '../toaster.service';

@Component({
    selector: 'search-movie',
    templateUrl: '../custom.component.html'
})

export class CustomComponent implements OnInit {

    constructor(
        private toasterService: ToasterService) {
    }

    ngOnInit() {
        this.toasterService.showToaster('Hello World');
    }
}

Output:

 

 

ANGULAR2: USING Toasters AS ANGULAR SERVICE IN ANGULAR 2 APPLICATION

Standard

Since toasters are essential component for any connected web application, we have couple of toasters component available in market for angular2, I am using primeng toaster…

Usage

Since toasters are used throughout the application, so its better to define it once in index.html and then try to set/reset through component code. I am also using BehaviorSubject object in service, which is way more awesome and better then observable in many cases, Behavior Subject is a type of subject, a subject is a special type of observable so you can subscribe to messages like any other observable. In plain words when specific page is invoked, its ngOnit() method call the toaster service and pass the reference of toaster value to be load, then service set new value into its BehaviorSubject object(toasterStatus), all variables(objToaster) throughout the application subscribed to this BehaviorSubject object are then alerted and refresh their state with the new value.

Index/main-component.html code:

<p-growl [value]="objToaster"></p-growl>

main-component.ts:

import { Component, OnInit, AfterViewInit } from '@angular/core';

import { Message } from 'primeng/primeng';
import { ToasterService } from './shared/service/alert.service';

@Component({
    selector: 'my-app',
    templateUrl: '../../Scripts/app/app.component.html'
})

export class AppComponent implements OnInit, AfterViewInit {
    objToaster: Message[];

    constructor(
        private toasterService: ToasterService) {
        this.objToaster = [];
    }

    ngOnInit() {
    }

    ngAfterViewInit() {
        this.toasterService.toasterStatus.subscribe((val: Message) => {
            if (val)
                this.objToaster.push(val);
        });
    }
}

toaster.service.ts:

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

import { Message } from 'primeng/primeng';

@Injectable()
export class ToasterService {
    public toasterStatus: BehaviorSubject<Message> = new BehaviorSubject<Message>(null);

    //type: success, info, warn, error
    showToaster(type: string, header: string, content: string) {
        let toasterObj: Message = { severity: type, summary: header, detail: content };
        this.toasterStatus.next(toasterObj);
    }

    hideToaster() {
        this.toasterStatus.next(null);
    }
}

custom-component.ts:

import { Component, OnInit } from '@angular/core';
import { ToasterService } from '../../shared/service/alert.service';

@Component({
    selector: 'search-movie',
    templateUrl: '../../Scripts/app/search-movies/movie.component.html'
})

export class SearchMovieComponent implements OnInit {

    constructor(
        private toasterService: ToasterService) {
    }

    ngOnInit() {
        this.toasterService.showToaster("info", "Search Movie header", "custom msg");
    }
}

Output:

screenshot_15 screenshot_16

P.S.

Please include primeng package in app.module.ts

import { GrowlModule } from 'primeng/primeng';