Published: November 23 2022

Angular 14 - Alert (Toaster) Notifications Tutorial & Example

Tutorial built with Angular 14.2.11

Other versions available:

In this tutorial we'll cover how to implement alert / toaster notification messages in Angular 14.

Alert notifications are a common requirement in web applications for displaying status messages to the user (e.g. error, success, warning and info alert messages).

Example Angular 14 Alerts App

The example app implements alerts in a custom Angular alert module, and contains the following two pages to demonstrate how the alerts work:

  • Single Alert (HomeComponent) - contains buttons for sending alerts to the default <alert> component located in the root app component template (/src/app/app.component.html). It also enables toggling of alert options using checkboxes.
  • Multiple Alerts (MultiAlertsComponent) - shows how multiple <alert> components can be used in the same page by assigning each of them a unique id and specifying which id to target when sending an alert message.

Styled with Bootstrap 5

The example is styled with the CSS from Bootstrap 5.2, for more info about Bootstrap see https://getbootstrap.com/docs/5.2/getting-started/introduction/.

If you're not using Bootstrap you can change the CSS classes on alert components in the cssClass() method of the alert component (/src/_alert/alert.component.ts), and update the HTML in the alert component template (/src/_alert/alert.component.html).

Code on GitHub

Project code is available on GitHub at https://github.com/cornflourblue/angular-14-alert-notifications.

Here it is in action:(See on StackBlitz at https://stackblitz.com/edit/angular-14-alerts)


Run the Angular 14 Alert Notifications Example Locally

  1. Install Node.js and npm from https://nodejs.org.
  2. Download or clone the tutorial project source code from https://github.com/cornflourblue/angular-14-alert-notifications.
  3. Install all required npm packages by running npm install or npm i from the command line in the project root folder (where the package.json is located).
  4. Start the application by running npm start from the command line in the project root folder, this will build the application and automatically launch it in the browser on the URL http://localhost:4200.

NOTE: You can also start the app with the Angular CLI command ng serve --open. To do this first install the Angular CLI globally on your system with the command npm install -g @angular/cli.


How to add Alerts to your Angular 14 App

To add alerts to your Angular application copy the /src/app/_alert folder from the example project into your project, the folder contains the following alert module and associated files:

  • alert.component.html - alert component template that contains the html for displaying alerts.
  • alert.component.ts - alert component with the logic for displaying alerts.
  • alert.model.ts - alert model class that defines the properties of an alert, it also includes the AlertType enum that defines the different types of alerts.
  • alert.module.ts - alert module that encapsulates the alert component so it can be imported by the app module.
  • alert.service.ts - alert service that can be used by any angular component or service to send alerts to alert components.
  • index.ts - barrel file that re-exports the alert module, service and model so they can be imported using only the folder path instead of the full path to each file, and also enables importing from multiple files with a single import.


Import the Alert Module into your App Module

To make the alert component available to your Angular 14 application you need to add the AlertModule to the imports array of your App Module (app.module.ts). See the app module from the example app below, the alert module is imported on line 5 and added to the imports array of the app module on line 16.

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';

import { AlertModule } from './_alert';
import { AppRoutingModule } from './app-routing.module';

import { AppComponent } from './app.component';
import { HomeComponent } from './home';
import { MultiAlertsComponent } from './multi-alerts';

@NgModule({
    imports: [
        BrowserModule,
        FormsModule,
        AlertModule,
        AppRoutingModule
    ],
    declarations: [
        AppComponent,
        HomeComponent,
        MultiAlertsComponent
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }


Add an <alert></alert> tag where you want alerts to be displayed

Add an alert component tag where you want alert messages to be displayed. If there's only one alert component on the page you don't need to specify an id (the default id is "default-alert"). Any additional alert components must have a unique id specified using the option below.

Alert Component Attributes

The alert component accepts the following optional attributes:

  • id - used if you want to display multiple alerts in different locations on the same page (see the Multiple Alerts page in the example above). An alert component with an id attribute will display messages sent via the alert service with a matching id, e.g. alertService.error('something broke!', { id: 'alert-1' }); will send an error message to the alert component with id="alert-1". Default value is "default-alert".
  • fade - controls if alert messages are faded out when closed. Default value is true.

Global Default Alert Component

The example app defines a global default alert component in the root app component template (/src/app/app.component.html). The <alert> component doesn't have an id, so messages sent to the alert service without an id (e.g. alertService.success('test angular 14 alert!');) will be displayed by the global default alert.

<!-- main app container -->
<div class="card text-bg-light mx-3">
    <div class="card-body text-center">
        <alert></alert>
        <router-outlet></router-outlet>
    </div>
</div>


Send Alerts with the Alert Service

Now that you've added the alert module and an alert component to your Angular app, you can send alert notifications from any component by injecting the alert service and calling one its methods (success(), error(), info(), warn()).

Alert method parameters

Each alert method takes the parameters (message: string, options?: AlertOptions):

  • The first parameter is a string for the alert message which can be a plain text or HTML.
  • The second parameter is an optional AlertOptions object that supports the following properties (all are optional):
    • id - the id of the <alert> component that will display the alert notification. Default value is "default-alert".
    • autoClose - if true the alert will automatically close the after three seconds. Default value is false.
    • keepAfterRouteChange - if true the alert will continue to display after one route change, which is useful to display an alert after an automatic redirect (e.g. after completing a form). Default value is false.


Example Home Component

The home component from the example app injects the alertService into its constructor() so it can be accessed in the home component template to send an alert when a button is clicked. In a real world application alerts can be triggered by any type of event, for example an error alert for a failed http request or a success alert after a form is submitted.

The options property contains alert options that are bound to the checkboxes in the home component template.

import { Component } from '@angular/core';

import { AlertService } from '../_alert';

@Component({ templateUrl: 'home.component.html' })
export class HomeComponent {
    options = {
        autoClose: false,
        keepAfterRouteChange: false
    };

    constructor(public alertService: AlertService) { }
}


Example Home Component Template

The home component template contains buttons for sending different alerts to the default alert component, and a couple of checkboxes for toggling alert options.

<h1>Angular 14 Alerts</h1>
<div class="my-4">
    <button class="btn btn-success m-1" (click)="alertService.success('Success!!', options)">Success</button>
    <button class="btn btn-danger m-1" (click)="alertService.error('Error :(', options)">Error</button>
    <button class="btn btn-info m-1" (click)="alertService.info('Some info....', options)">Info</button>
    <button class="btn btn-warning m-1" (click)="alertService.warn('Warning: ...', options)">Warn</button>
    <button class="btn btn-outline-dark m-1" (click)="alertService.clear()">Clear</button>
</div>
<h5>Alert Options</h5>
<div class="form-check mb-2">
    <div class="form-check-inline">
        <input type="checkbox" name="autoClose" id="autoClose" class="form-check-input" [(ngModel)]="options.autoClose">
        <label for="autoClose" class="form-check-label">Auto close alert after three seconds</label>
    </div>
</div>
<div class="form-check">
    <div class="form-check-inline">
        <input type="checkbox" name="keepAfterRouteChange" id="keepAfterRouteChange" class="form-check-input" [(ngModel)]="options.keepAfterRouteChange">
        <label for="keepAfterRouteChange">Display alert after one route change</label>
    </div>
</div>

 


 

Inside the Angular 14 Alert Module

Below is a breakdown of the pieces of code used to implement the alerts example in Angular 14, you don't need to know all the details of how it works to use the alert module in your project, it's only if you're interested in the nuts and bolts or want to modify the code or behaviour.

Alert Module Files


Alert Service

Path: /src/app/_alert/alert.service.ts

The alert service acts as the bridge between any component in an Angular application and the alert component that actually displays the alert / toaster messages. It contains methods for sending, clearing and subscribing to alert messages.

The service uses the RxJS Observable and Subject classes to enable communication with other components, for more information on how this works see Angular 14 - Communicating Between Components with RxJS Observable & Subject.

import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { filter } from 'rxjs/operators';

import { Alert, AlertType, AlertOptions } from './alert.model';

@Injectable({ providedIn: 'root' })
export class AlertService {
    private subject = new Subject<Alert>();
    private defaultId = 'default-alert';

    // enable subscribing to alerts observable
    onAlert(id = this.defaultId): Observable<Alert> {
        return this.subject.asObservable().pipe(filter(x => x && x.id === id));
    }

    // convenience methods
    success(message: string, options?: AlertOptions) {
        this.alert(new Alert({ ...options, type: AlertType.Success, message }));
    }

    error(message: string, options?: AlertOptions) {
        this.alert(new Alert({ ...options, type: AlertType.Error, message }));
    }

    info(message: string, options?: AlertOptions) {
        this.alert(new Alert({ ...options, type: AlertType.Info, message }));
    }

    warn(message: string, options?: AlertOptions) {
        this.alert(new Alert({ ...options, type: AlertType.Warning, message }));
    }

    // main alert method    
    alert(alert: Alert) {
        alert.id = alert.id || this.defaultId;
        this.subject.next(alert);
    }

    // clear alerts
    clear(id = this.defaultId) {
        this.subject.next(new Alert({ id }));
    }
}


Alert Component

Path: /src/app/_alert/alert.component.ts

The alert component controls the adding & removing of alerts in the UI, it maintains an array of alerts that are rendered by the component template.

The ngOnInit method subscribes to the observable returned from the alertService.onAlert() method, this enables the alert component to be notified whenever an alert message is sent to the alert service and add it to the alerts array for display. Sending an alert with an empty message to the alert service tells the alert component to clear the alerts array. This method also calls router.events.subscribe() to subscribe to route change events so it can automatically clear alerts on route changes.

The ngOnDestroy() method unsubscribes from the alert service and router when the component is destroyed to prevent memory leaks from orphaned subscriptions.

The removeAlert() method removes the specified alert object from the array, it allows individual alerts to be closed in the UI.

The cssClass() method returns a corresponding bootstrap alert class for each of the alert types, if you're using something other than bootstrap you can change the CSS classes returned to suit your application.

import { Component, OnInit, OnDestroy, Input } from '@angular/core';
import { Router, NavigationStart } from '@angular/router';
import { Subscription } from 'rxjs';

import { Alert, AlertType } from './alert.model';
import { AlertService } from './alert.service';

@Component({ selector: 'alert', templateUrl: 'alert.component.html' })
export class AlertComponent implements OnInit, OnDestroy {
    @Input() id = 'default-alert';
    @Input() fade = true;

    alerts: Alert[] = [];
    alertSubscription!: Subscription;
    routeSubscription!: Subscription;

    constructor(private router: Router, private alertService: AlertService) { }

    ngOnInit() {
        // subscribe to new alert notifications
        this.alertSubscription = this.alertService.onAlert(this.id)
            .subscribe(alert => {
                // clear alerts when an empty alert is received
                if (!alert.message) {
                    // filter out alerts without 'keepAfterRouteChange' flag
                    this.alerts = this.alerts.filter(x => x.keepAfterRouteChange);

                    // remove 'keepAfterRouteChange' flag on the rest
                    this.alerts.forEach(x => delete x.keepAfterRouteChange);
                    return;
                }

                // add alert to array
                this.alerts.push(alert);

                // auto close alert if required
                if (alert.autoClose) {
                    setTimeout(() => this.removeAlert(alert), 3000);
                }
           });

        // clear alerts on location change
        this.routeSubscription = this.router.events.subscribe(event => {
            if (event instanceof NavigationStart) {
                this.alertService.clear(this.id);
            }
        });
    }

    ngOnDestroy() {
        // unsubscribe to avoid memory leaks
        this.alertSubscription.unsubscribe();
        this.routeSubscription.unsubscribe();
    }

    removeAlert(alert: Alert) {
        // check if already removed to prevent error on auto close
        if (!this.alerts.includes(alert)) return;

        // fade out alert if this.fade === true
        const timeout = this.fade ? 250 : 0;
        alert.fade = this.fade;

        setTimeout(() => {
            // filter alert out of array
            this.alerts = this.alerts.filter(x => x !== alert);
        }, timeout);
    }

    cssClass(alert: Alert) {
        if (!alert) return;

        const classes = ['alert', 'alert-dismissible'];
                
        const alertTypeClass = {
            [AlertType.Success]: 'alert-success',
            [AlertType.Error]: 'alert-danger',
            [AlertType.Info]: 'alert-info',
            [AlertType.Warning]: 'alert-warning'
        }

        if (alert.type !== undefined) {
            classes.push(alertTypeClass[alert.type]);
        }

        if (alert.fade) {
            classes.push('fade');
        }

        return classes.join(' ');
    }
}


Alert Component Template

Path: /src/app/_alert/alert.component.html

The alert component template renders an alert message for each alert in the alerts array using the Angular *ngFor directive.

Bootstrap 5.2 is used for styling the alerts / toaster notifications in the example, you can change the HTML and CSS classes in this template to suit your application if you're not using Bootstrap.

<div *ngFor="let alert of alerts" class="{{cssClass(alert)}}">
    <div [innerHTML]="alert.message"></div>
    <button type="button" class="btn-close" (click)="removeAlert(alert)"></button>
</div>


Alert Models

Path: /src/app/_alert/alert.model.ts

The alert model file contains the Alert, AlertType and AlertOptions models.

  • Alert defines the properties of each alert object.
  • AlertType is an enumeration containing the types of alerts.
  • AlertOptions defines the options available when sending an alert to the alert service.
export class Alert {
    id?: string;
    type?: AlertType;
    message?: string;
    autoClose?: boolean;
    keepAfterRouteChange?: boolean;
    fade?: boolean;

    constructor(init?:Partial<Alert>) {
        Object.assign(this, init);
    }
}

export enum AlertType {
    Success,
    Error,
    Info,
    Warning
}

export class AlertOptions {
    id?: string;
    autoClose?: boolean;
    keepAfterRouteChange?: boolean;
}


Angular Alert Module

Path: /src/app/_alert/alert.module.ts

The AlertModule encapsulates the alert component so it can be imported and used by other Angular modules.

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { AlertComponent } from './alert.component';

@NgModule({
    imports: [CommonModule],
    declarations: [AlertComponent],
    exports: [AlertComponent]
})
export class AlertModule { }

 


Need Some Angular 14 Help?

Search fiverr for freelance Angular 14 developers.


Follow me for updates

On Twitter or RSS.


When I'm not coding...

Me and Tina are on a motorcycle adventure around Australia.
Come along for the ride!


Comments


Supported by