In my older AngularJS applications, I used a jQuery plug-in plus AngularJS singleton “notification” service whenever I wanted to display toast/growl notifications. With the newer Angular framework, I started going down this path, but did also play around with an Angular module that provides this functionality.
The old stand-by toast mechanism I have always used is toastr. It’s a jquery plugin that does pretty much everything I want. There is also an Angular module called ng2-toasty2 with which it is easy to integrate.
Both have demos:
https://codeseven.github.io/toastr/demo.html
https://akserg.github.io/ng2-webpack-demo/#/toasty
Rather than focusing on how the modules/plugins work, I made my own notificationService that can be injected. The basic service will expose various toast types.
import { Injectable } from '@angular/core'; import * as $ from 'jquery'; import * as toastr from 'toastr'; @Injectable() export class NotificationService { private toastr: any; private toastrOptions: any; private defaultSuccess: string = "Success!"; private defaultError: string = "Error!"; private defaultInfo: string = "Info"; constructor() { this.toastr = <any>toastr; this.toastrOptions = <any>toastrOptions; // Set defaults this.toastrOptions = { positionClass: 'toast-bottom-right' }; this.toastr.options = this.toastrOptions; } success(message?: string) { this.displayToast(message || this.defaultSuccess, 'success'); }; error(message?: string) { this.displayToast(message || this.defaultError, 'error'); }; info(message?: string) { this.displayToast(message || this.defaultInfo, 'info'); }; warning(message) { this.displayToast(message, 'warning'); }; private displayToast(message: string, type: string) { switch (type) { case 'default': this.toastr.default(message); break; case 'info': this.toastr.info(message); break; case 'success': this.toastr.success(message); break; case 'wait': this.toastr.wait(message); break; case 'error': this.toastr.error(message); break; case 'warning': this.toastr.warning(message); break; } } }
After creating the service, we have to have a reference to the toastr js and css files. If using webpack, if you’ll notice the import above, we have to use the webpack.ProvidePlugin to expose the toastr global object. You can view the source code links below to see how to integrate with webpack. It is not really straight-foward, imho, to integrate with jquery plugins from within Angular or TypeScript.
Note the importing of the toastr global object. Now, from within any module/component/directive, we can simply inject the notification service and create toast messages!
As I mentioned, there is also ng2-toasty. It may or may not be a better solution. You can read through the documentation that details how to setup it up (module includes, placeholder element in your DOM, etc). The basic notificationService changes very little, though. We only have to inject toasty’s service within our service and change the “displayToast” method.
import { Injectable } from '@angular/core'; import { ToastyService, ToastyConfig, ToastyComponent, ToastOptions, ToastData } from 'ng2-toasty'; import { Subject, Observable, Subscription } from 'rxjs/Rx'; @Injectable() export class NotificationService { constructor(private toastyService: ToastyService) { } success(message: string) { this.displayToast(message, 'success'); }; error(message) { this.displayToast(message, 'error'); }; info(message) { this.displayToast(message, 'info'); }; warning(message) { this.displayToast(message, 'warning'); }; private displayToast(message: string, type: string) { let interval = 1000; let timeout = 5000; let seconds = timeout / 1000; let subscription: Subscription; let toastOptions: ToastOptions = { title: '', msg: message, showClose: true, timeout: timeout, theme: 'bootstrap', onAdd: (toast: ToastData) => { }, onRemove: function (toast: ToastData) { } }; switch (type) { case 'default': this.toastyService.default(toastOptions); break; case 'info': this.toastyService.info(toastOptions); break; case 'success': this.toastyService.success(toastOptions); break; case 'wait': this.toastyService.wait(toastOptions); break; case 'error': this.toastyService.error(toastOptions); break; case 'warning': this.toastyService.warning(toastOptions); break; } } }
You can already see some benefits to using the Angular toasty module. It has exposed TypeScript/Angular objects for setting options and interacting with the toast.
I haven’t created plunker demos for these code snippets yet, but you can see the toastr version working on my Azure site.
Commit for toasty2: https://github.com/long2know/angular-core-demo/commit/ee2785bdbb02d55aacf50a865d876d520e981555
Commit for toastr: https://github.com/long2know/angular-core-demo/commit/9703133d2f0b24330cb219b8fa3ef9458d5c6ec3