Implement Toast with Bootstrap 5 in Angular 15 or 16 | Tutorial

Introduction
In the context of an Angular project, Toast typically refers to a notification or toast message library that is used to display temporary messages or notifications to the user. Toast messages are typically small pop-up boxes that appear on the screen to provide information or feedback to the user.
In this blog post, I will provide a code walkthrough on how to utilize an Angular service to display the toast component using Bootstrap 5. This service will enable passing data into the toast component for display purposes.
Use Case
I have a data entry form for a position record. When the user clicks the Update button in your form, I want to display a toast message to notify them that the position has been successfully updated. Please refer to the screenshot below for more details:

Tutorial Content
I have published a blog series titled Fullstack Angular 15, Bootstrap 5 & .NET 7 API: Project Demo and Tutorial. In this series, I provide a comprehensive guide along with a project demo. You have the option to download the complete full-stack source code and run it on your localhost environment.
In this blog post, I will specifically focus on a crucial code snippet that demonstrates how to call an Angular service and display a toast using the @ng-bootstrap/ng-bootstrap library. By following this code snippet, you will be able to grasp the implementation details and effectively utilize the toast service in your Angular application.
@ng-bootstrap/ng-bootstrapis a library that provides Angular directives and components to easily integrate and use Bootstrap's CSS and JavaScript components in Angular applications.
To implement the toast, follow these steps:
- Create the standalone component using
ngb-toastcomponent from the@ng-bootstrap/ng-bootstraplibrary. - In the
app.component.htmlfile, wire the toast component by including its selector or placing it within the desired section of your application's template. This will ensure that the toast component is rendered and displayed as needed. - Create a toast service that allows the calling of the toast component. The toast service should contain methods or functions that can be used to trigger and display the notification. You can implement the logic for displaying different types of toasts, such as success messages, error messages, or informational alerts, within this service.
- Finally, call the toast service from the component where you want to display the notification. Use the appropriate method or function provided by the toast service to show the desired toast message. You can pass parameters such as the message content, duration, and toast type to customize the notification according to your requirements.
By following these steps, you will be able to implement a toast functionality in your Angular application, allowing you to display informative and user-friendly notifications.
Part 1: Toast Component Source Code
An Angular component is a fundamental building block of Angular applications. It is a self-contained piece of code that encapsulates the data, behavior, and presentation logic of a part of the user interface (UI).
In the ng-bootstrap library, the component ngb-toast provides feedback messages as notifications to the user. Now, let’s assume you have a component where you want to display toast notifications. In the template of that component, you can use the ngb-toast component as follows as shown in the source code file toasts-container.component.html
<ngb-toast
*ngFor="let toast of toastService.toasts"
[class]="toast.classname"
[header]="toast.header"
[autohide]="true"
[delay]="toast.delay || 5000"
(hidden)="toastService.remove(toast)"
>
<ng-template [ngIf]="isTemplate(toast)" [ngIfElse]="text">
<ng-template [ngTemplateOutlet]="toast.textOrTpl"></ng-template>
</ng-template>
<ng-template #text>{{ toast.textOrTpl }}</ng-template>
</ngb-toast>In the above code, the component iterates over the toastService.toasts array and creates a toast for each item in the array. Let's go through the code and explain each part:
- The
<ngb-toast>component is used to display toast notifications. It is repeated using the*ngFordirective to iterate over thetoastService.toastsarray, creating a toast for each item. - The
[class],[header],[autohide], and[delay]bindings are used to set various properties of the toast. Thetoast.classnamebinds to theclassproperty,toast.headerbinds to theheaderproperty, andtoast.delaysets the delay for the toast to automatically hide. Iftoast.delayis not provided, a default value of 5000 milliseconds (5 seconds) is used. - The
(hidden)event binding listens for the toast being hidden or dismissed, triggering thetoastService.remove(toast)method to remove the toast from thetoastService.toastsarray. - The first
<ng-template>element uses[ngIf]and[ngIfElse]directives to conditionally render content based on whether thetoast.textOrTplproperty is a template or plain text. If it is a template, the[ngTemplateOutlet]directive is used to render the template. Otherwise, it falls back to thetexttemplate. - The second
<ng-template>element with the#textreference variable is used as a fallback for plain text content. It displays thetoast.textOrTplvalue as text if it is not a template.
Here is the source code of the ToastsContainer in the source code file toasts-container.component.ts
import { Component, TemplateRef } from '@angular/core';
import { ToastService } from '@app/services/toast/toast.service';
import { NgFor, NgIf, NgTemplateOutlet } from '@angular/common';
import { NgbToastModule } from '@ng-bootstrap/ng-bootstrap';
@Component({
selector: 'app-toasts',
standalone: true,
imports: [NgbToastModule, NgIf, NgTemplateOutlet, NgFor],
templateUrl: './toasts-container.component.html',
host: { class: 'toast-container position-fixed top-0 end-0 p-3', style: 'z-index: 1200' },
})
export class ToastsContainer {
constructor(public toastService: ToastService) {}
isTemplate(toast: any) {
return toast.textOrTpl instanceof TemplateRef;
}
}In the above code, we import the necessary dependencies, including Component and TemplateRef from @angular/core, and ToastService from a custom path. Then we define the ToastsContainer component using the @Component decorator. The component's selector is set to 'app-toasts', and the template file is specified with templateUrl. The host property is used to define the host element's attributes.
Inside the component class, we have a constructor that injects the ToastService instance into the component. The isTemplate() method is defined to check whether a toast's content is a template or plain text, based on the textOrTpl property.
For more information on how to use the ngb-toast, please visit online documentation.
Part 2: App Component Source Code
The app.component.html file in Angular is the template file associated with the root component of your Angular application, which is typically named AppComponent. It represents the HTML structure and content that will be rendered when the component is displayed.
The app.component.html file is where you define the layout, structure, and content of your application's root component. It typically contains HTML markup along with Angular template syntax, such as directives, data binding, and other Angular-specific syntax.
Here’s the source code in the source code file app.component.html.
<router-outlet></router-outlet>
<app-toasts aria-live="polite" aria-atomic="true"></app-toasts>Let’s examine the code
<router-outlet></router-outlet>: The<router-outlet>is a placeholder directive provided by Angular for dynamically rendering components based on the current route. It is typically placed in the template file of the root component. The routed components will replace this placeholder based on the active route.<app-toasts aria-live="polite" aria-atomic="true"></app-toasts>: The<app-toasts>component represents the customToastsContainercomponent in your application. It is responsible for displaying toast notifications. Here, it is included in the template to render the toast notifications. Thearia-liveattribute is set to"polite"to ensure that notifications are announced by screen readers without interrupting the current speech. Thearia-atomicattribute is set to"true"to indicate that the entire region should be considered as a whole for accessibility purposes.
Part 3: Angular Toast Service Source Code
In Angular, a service is a class that is responsible for providing specific functionality and data to different parts of an application. Services act as a bridge between components, allowing them to share data, perform common tasks, and encapsulate business logic.
Here is the source code for the ToastService taken from the toaster.service.ts file:
import { Injectable, TemplateRef } from '@angular/core';
@Injectable({ providedIn: 'root' })
export class ToastService {
toasts: any[] = [];
show(header: string, textOrTpl: string | TemplateRef<any>, options: any = {}) {
this.toasts.push({ header, textOrTpl, ...options });
}
remove(toast: any) {
this.toasts = this.toasts.filter((t) => t !== toast);
}
clear() {
this.toasts.splice(0, this.toasts.length);
}
}The code snippet is an Angular service called ToastService. This service is responsible for managing toast messages in an Angular application.
Explanation of the code:
- The
ToastServiceis decorated with@Injectable({ providedIn: 'root' }). This ensures that the service is available at the root level of your application and can be injected into other components. - The
toastsproperty is an array that holds the toast messages. Each toast message is an object with properties likeheader,textOrTpl, andoptions. - The
show()method is used to add a new toast message. It takes three parameters:header(a string representing the toast header),textOrTpl(a string or aTemplateRefrepresenting the content of the toast message), andoptions(an optional object to provide additional options for the toast). - Inside the
show()method, a new toast object is created by combining the provided parameters with theoptionsobject using the spread operator. The new toast is then added to thetoastsarray using thepush()method. - The
remove()method is used to remove a specific toast from thetoastsarray. It takes the toast object as a parameter and filters out that toast from the array. - The
clear()method is used to remove all the toast messages from thetoastsarray. It achieves this by using thesplice()method to remove all elements starting from index 0.
By using the ToastService in your Angular application, you can call the show() method to add toast messages, the remove() method to remove specific toasts, and the clear() method to remove all toasts. This service provides a convenient way to manage and display toast messages throughout your application.
Part 4: Position Detail Component Source Code (example of calling ToasterService to display Toaster Container)
In Angular, a component is a fundamental building block that encapsulates the functionality, data, and user interface (UI) of a specific part of a web application. Components are responsible for controlling and rendering a portion of the application’s user interface.
Here is the source code for the PositionDetailComponent taken from the position-detail.component.ts file:
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { UntypedFormGroup, UntypedFormBuilder, Validators } from '@angular/forms';
import { Logger } from '@app/core';
import { ApiHttpService } from '@app/services/api/api-http.service';
import { ApiEndpointsService } from '@app/services/api/api-endpoints.service';
import { Position } from '@shared/interfaces/position';
import { DataResponsePosition } from '@shared/interfaces/data-response-position';
import { ModalService } from '@app/services/modal/modal.service';
import { RxwebValidators } from '@rxweb/reactive-form-validators';
import { ToastService } from '@app/services/toast/toast.service';
const log = new Logger('Detail');
@Component({
selector: 'app-detail',
templateUrl: './position-detail.component.html',
styleUrls: ['./position-detail.component.scss'],
})
export class PositionDetailComponent implements OnInit {
formMode = 'New';
sub: any;
id: any;
entryForm!: UntypedFormGroup;
error: string | undefined;
position!: Position;
isAddNew: boolean = false;
constructor(
private toastService: ToastService,
private route: ActivatedRoute,
private formBuilder: UntypedFormBuilder,
private apiHttpService: ApiHttpService,
private apiEndpointsService: ApiEndpointsService,
private modalService: ModalService,
) {
this.createForm();
}
ngOnInit() {
this.sub = this.route.params.subscribe((params) => {
this.id = params['id'];
if (this.id !== undefined) {
this.read(this.route.snapshot.paramMap.get('id'));
this.formMode = 'Edit';
} else {
this.isAddNew = true;
this.formMode = 'New';
}
});
log.debug('ngOnInit:', this.id);
}
// Handle Create button click
onCreate() {
this.create(this.entryForm.value);
log.debug('OnInsert: ', this.entryForm.value);
log.debug('OnInsert: ', this.entryForm.get('positionNumber')!.value);
}
// Handle Update button click
onUpdate() {
this.put(this.entryForm.get('id')!.value, this.entryForm.value);
this.showToaster('Great job!', 'Data is updated');
}
// Handle Delete button click
onDelete() {
this.modalService
.OpenConfirmDialog('Position deletion', 'Are you sure you want to delete?')
.then((Yes) => {
if (Yes) {
this.delete(this.entryForm.get('id')!.value);
log.debug('onDelete: ', this.entryForm.value);
}
})
.catch(() => {
log.debug('onDelete: ', 'Cancel');
});
}
// CRUD > Read, map to REST/HTTP GET
read(id: any): void {
this.apiHttpService.get(this.apiEndpointsService.getPositionByIdEndpoint(id), id).subscribe(
//Assign resp to class-level model object.
(resp: DataResponsePosition) => {
//Assign data to class-level model object.
this.position = resp.data;
//Populate reactive form controls with model object properties.
this.entryForm.setValue({
id: this.position.id,
positionNumber: this.position.positionNumber,
positionTitle: this.position.positionTitle,
positionDescription: this.position.positionDescription,
positionSalary: this.position.positionSalary,
});
},
(error) => {
log.debug(error);
}
);
}
// CRUD > Delete, map to REST/HTTP DELETE
delete(id: any): void {
this.apiHttpService.delete(this.apiEndpointsService.deletePositionByIdEndpoint(id), id).subscribe(
(resp: any) => {
log.debug(resp);
this.showToaster('Great job!', 'Data is deleted');
this.entryForm.reset();
this.isAddNew = true;
},
(error) => {
log.debug(error);
}
);
}
// CRUD > Create, map to REST/HTTP POST
create(data: any): void {
this.apiHttpService.post(this.apiEndpointsService.postPositionsEndpoint(), data).subscribe((resp: any) => {
this.id = resp.data; //guid return in data
this.showToaster('Great job!', 'Data is inserted');
this.entryForm.reset();
});
}
// CRUD > Update, map to REST/HTTP PUT
put(id: string, data: any): void {
this.apiHttpService.put(this.apiEndpointsService.putPositionsPagedEndpoint(id), data).subscribe((resp: any) => {
this.id = resp.data; //guid return in data
});
}
// reactive form
private createForm() {
this.entryForm = this.formBuilder.group({
id: [''],
positionNumber: ['', Validators.required],
positionTitle: ['', Validators.required],
positionDescription: ['', Validators.required],
positionSalary: ['', RxwebValidators.numeric({ allowDecimal: true, isFormat: false })],
});
}
// call modal service
showToaster(title: string, message: string) {
this.toastService.show(title, message, {
classname: 'bg-success text-light',
delay: 2000,
autohide: true
});
}
}The provided code is a TypeScript class PositionDetailComponent, which represents a component in an Angular application responsible for displaying the details of a position record.
Explanation of the code pertains to toast service:
- The component imports necessary dependencies such as
Component,OnInit, and various services, specifically theToasterServcie - The
delete()method sends a request to delete a position and shows a toast notification upon success. - The
create()method sends a request to create a new position and shows a toast notification upon success. - The
showToaster()method is responsible for displaying toast messages using theToastService. It is called when certain actions are performed, such as successful updates or deletions.
This code provides functionality for managing position details, including CRUD operations and toast notifications.
Source Code
Recommended Contents
- What are Services in Angular? ⛅
- What is standalone component in Angular? ⛳
- Upgrading Angular 15 to 16: A Full-stack Web Development Project using Angular and .NetCore WebAPI ♥
- Load Angular Component into Bootstrap Modal | Tutorial ⛽
- Fullstack Angular 15, Bootstrap 5 & NET 7 API: Project Demo and Tutorial ♥
- Seven Object-Oriented Programming Jokes ☺
Summary
The tutorial demonstrates how to create a toast in Angular using Bootstrap. It walks through the process of setting up the necessary components, services, and templates to achieve the desired functionality.





