Adding a Spinner to Angular App on Outgoing HTTP Calls

Introduction

In Angular apps, it’s common to have to make HTTP calls to APIs. These calls can take some time to complete, which can leave the user wondering if the app is still working. To solve this issue, we can add a spinner to our Angular app that shows up whenever an HTTP call is made. In this tutorial, we’ll learn how to add a spinner to our Angular app using an HTTP interceptor.

In this tutorial, we will explore how to implement a loading spinner in an Angular application using an HTTP interceptor and a spinner service. We will start by creating a spinner service that will be used to show or hide the spinner. Then, we will create an HTTP interceptor that will watch for outgoing HTTP calls and show the spinner when they are made. Finally, we will update our app component to show the spinner on the screen.

To automatically show a spinner whenever an outgoing HTTP call is made in an Angular application, you can create an HTTP interceptor. An interceptor is a middleware that intercepts outgoing HTTP requests and responses.

Here are the steps you can follow to create an HTTP interceptor that shows a spinner:

Prerequisites

Before we begin, make sure you have the following installed:

  • Node.js
  • Angular CLI

Creating a New Angular App

If you don’t already have an Angular app, you can create a new one by running the following command:

ng new my-app

Demo

This will create a new Angular app in a directory called my-app.

Adding a Spinner to Angular App

To add a spinner to our Angular app, we’ll first create a new service that will keep track of when HTTP calls are made. We’ll call this service SpinnerService. Here’s the code for this service:

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class SpinnerService {
  private spinnerCounter = 0;
  spinnerCounter$ = new BehaviorSubject<number>(0);

  constructor() { }

  show() {
    this.spinnerCounter++;
    this.spinnerCounter$.next(this.spinnerCounter);
  }

  hide() {
    if (this.spinnerCounter > 0) {
      this.spinnerCounter--;
    }
    this.spinnerCounter$.next(this.spinnerCounter);
  }
}

This service keeps track of the number of HTTP calls currently being made by incrementing and decrementing a counter using the show and hide methods. The spinnerCounter$ variable is a BehaviorSubject that emits the current value of the counter.

Next, we’ll create an HTTP interceptor that will intercept all outgoing HTTP calls and call the show and hide methods of our SpinnerService. Here’s the code for this interceptor:

import { Injectable } from '@angular/core';
import {
  HttpEvent,
  HttpHandler,
  HttpInterceptor,
  HttpRequest
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { finalize } from 'rxjs/operators';
import { SpinnerService } from './spinner.service';

@Injectable()
export class SpinnerInterceptor implements HttpInterceptor {

  constructor(private spinnerService: SpinnerService) {}

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    this.spinnerService.show();
    return next.handle(request).pipe(
      finalize(() => {
        this.spinnerService.hide();
      })
    );
  }
}

This interceptor intercepts all outgoing HTTP calls and calls the show method of our SpinnerService. When the HTTP call completes, it calls the hide method of our SpinnerService.

Now that we have our SpinnerService and SpinnerInterceptor, we need to include them in our app. We’ll add the SpinnerService to our app.module.ts file:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { HttpInterceptorService } from './http-interceptor.service';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, HttpClientModule],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: HttpInterceptorService,
      multi: true
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

Include this HTML in App Component.

   <div class="overlay show" *ngIf="spinnerService.spinnerCounter$ | async">
      <div class="spinner-border" role="status">
        <span class="visually-hidden">Loading...</span>    
      </div>
    </div>

Use the below CSS for the spinner, place this in app.component.css

.toolbar-spacer {
  flex: 1 1 auto;
}

a.title {
  color: white;
}

.footer-text {
  font-size: small;
  text-align: center;
  flex: 1 1 auto;
}

.toolbar-spacer {
  flex: 1 1 auto;
}

a.title {
  color: white;
}

.footer-text {
  font-size: small;
  text-align: center;
  flex: 1 1 auto;
}

.toolbar-spacer {
  flex: 1 1 auto;
}

a.title {
  color: white;
}

.footer-text {
  font-size: small;
  text-align: center;
  flex: 1 1 auto;
}

.spinner-border {
  position: fixed;
  top: 50%;
  left: 50%;  
  width: 2rem;
  height: 2rem;
  vertical-align: text-bottom;
  border: 0.25em solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: spinner-border 0.75s linear infinite;
  animation-timing-function: linear; 
  z-index: 9999;
}

@keyframes spinner-border {
  to {
    transform: rotate(360deg);
  }
}

.visually-hidden {
  position: absolute !important;
  height: 1px;
  width: 1px;
  overflow: hidden;
  clip: rect(1px, 1px, 1px, 1px);
  white-space: nowrap;
}

.overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.2);
  z-index: 9998;
  display: none;
}

.overlay.show {
  display: block;
}

Application Source Code @ LearnSmartCoding GitHub

Check out other topics that might interest you.

Conclusion.

To sum up, incorporating an Angular app spinner HTTP interceptor can greatly enhance the user experience by providing visual feedback during outgoing HTTP calls. By adding a spinner to the application, users are reassured that their requests are being processed and can avoid frustration from having to wait for long periods without any indication of progress. The use of an interceptor also simplifies the implementation process and reduces the likelihood of errors by providing a centralized location to manage outgoing HTTP calls. Overall, integrating an Angular app spinner HTTP interceptor is an effective way to improve the user experience and streamline the application’s functionality.

Leave a Reply

Your email address will not be published. Required fields are marked *

Verified by MonsterInsights