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. @Component({
  4. selector: 'spinner-view',
  5. templateUrl: 'spinner-view.component.html',
  6. })
  7. export class SpinnerComponent {
  8. constructor(public dialogRef: MatDialogRef<SpinnerComponent>
  9. , @Inject(MAT_DIALOG_DATA) public data: any) {}
  10. }
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. MatDialogModule,
  3. MatProgressSpinnerModule,
  4. } from '@angular/material';
  5. ......
  6. imports: [
  7. MatDialogModule,
  8. MatProgressSpinnerModule,
  9. ],
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. @Injectable()
  6. export class SpinnerService {
  7. constructor(private router: Router, private dialog: MatDialog) {
  8. }
  9. start(message?): MatDialogRef<SpinnerComponent> {
  10. const dialogRef = this.dialog.open(SpinnerComponent,{
  11. disableClose: true ,
  12. data: message == ''|| message == undefined ? "Loading..." : message
  13. });
  14. return dialogRef;
  15. };
  16. stop(ref:MatDialogRef<SpinnerComponent>){
  17. ref.close();
  18. }
  19. }
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. }
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.