Use Angular Material Dialog As Spinner

Introduction

 
Recently, while working on a project, I struggled in blocking the user interaction when calling the API. I tried to use third party components for a spinner but it won't look good with Angular Material design. So, finally, I solved it by using Angular Dialog as a spinner and disabled the "Close" button. Every developer knows that spinner is a very significant component in SPA and is used on almost every screen we develop. So, I implemented a reusable component.
 
Step 1 - Create a Spinner Component
 
Create a component by name SpinnerComponent, as shown below.
or 
If you are using Angular CLI, use the following command.
 
ng g component spinner-view
 
The structure looks like below.
 
Use Angular Material Dialog As Spinner
 
Open the component file and import MatDialogRef, MAT_DIALOG_DATA from @angular/material package. Here, we need to install Angular Material before importing this.
  1. import { MatDialogRef, MAT_DIALOG_DATA} from '@angular/material';  
Add the required varaibles in the constructor. 
  1. constructor(public dialogRef: MatDialogRef<SpinnerComponent>   
  2.     , @Inject(MAT_DIALOG_DATA) public data: any) {}  
  3. }  
Also, add an onclick method. Finally, the overall component looks like below.
  1. import {Component, Inject} from '@angular/core';  
  2. import { MatDialogRef, MAT_DIALOG_DATA} from '@angular/material';  
  3.   
  4. @Component({  
  5.     selector: 'spinner-view',  
  6.     templateUrl: 'spinner-view.component.html',  
  7.   })  
  8.   export class SpinnerComponent {  
  9.     
  10.     constructor(public dialogRef: MatDialogRef<SpinnerComponent>   
  11.       , @Inject(MAT_DIALOG_DATA) public data: any) {}  
  12.   
  13.   }  
In the View, add spinner and its configuration. The View looks like this.
  1. <mat-spinner  [diameter]="50" style="margin: 0 auto;"></mat-spinner>  
  2. <span>{{data}}</span>  
Step 2
 
Import the MatDialogModule, MatProgressSpinnerModule in Appmodule.
  1. import {   
  2.    
  3.     MatDialogModule,  
  4.     MatProgressSpinnerModule,  
  5.     
  6. } from '@angular/material';  
  7.   
  8. ......  
  9.   
  10.   imports: [  
  11.   
  12.     MatDialogModule,  
  13.     MatProgressSpinnerModule,  
  14.       
  15.   ],  
Step 3 - Create Spinner reusable service. 
 
Create an export Injectable class with the name spinner.service.ts. Import MatDialog from @angular/material and create a varable in constructor. Also, implement the stop and start methods like below.
  1. import { EventEmitter, Injectable } from '@angular/core';  
  2. import { Event, NavigationEnd, Router } from '@angular/router';  
  3. import { MatDialog, MatDialogRef } from '@angular/material';  
  4. import { SpinnerComponent } from './spinner-view/spinner-view.component';  
  5.   
  6. @Injectable()  
  7. export class SpinnerService {  
  8.   
  9.   
  10.     constructor(private router: Router, private dialog: MatDialog) {  
  11.   
  12.     }  
  13.   
  14.     start(message?): MatDialogRef<SpinnerComponent> {  
  15.         
  16.         const dialogRef = this.dialog.open(SpinnerComponent,{  
  17.             disableClose: true ,  
  18.             data: message == ''|| message == undefined ? "Loading..." : message  
  19.         });  
  20.         return dialogRef;  
  21.       };  
  22.   
  23.     stop(ref:MatDialogRef<SpinnerComponent>){  
  24.         ref.close();  
  25.     }    
  26. }  
The Spinner service is ready to use. Add this service in providers in the appmodule.ts file and start using it.  
 
Step 4 - Usage
 
Let us see how to use this while calling the APIs.
 
Import the spinner service in the component where you want to use the spinner.
  1. import { SpinnerService } from './../../services/spinner/spinner.service';  
Create a vairable in constructor.
  1. constructor(private spinnerService: SpinnerService) {      
  2.       
  3.     }    
Use spinner service like below while calling the API.
  1. var spinnerRef = this.spinnerService.start();  
  2.        this.YourService.YourAPi().pipe(finalize(() => {  
  3.            this.spinnerService.stop(spinnerRef);  
  4.        })).subscribe(res => {  
  5.         }, err => {   
  6.            }  
  7.        )  
Use Angular Material Dialog As Spinner
 
Step 5 - Customize loading text
 
Pass the text to the start method of spinner service to get a customized text with spinner like below.
  1. var spinnerRef = this.spinnerService.start("Customized loading text here");   


Summary

 
In this article, I discussed how we can create a spinner reusable service in Angular Material using Angular Material Dialog. We also saw how to pass our own loading text to the spinner. I hope this article helps you all.