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.
- How to Create a Custom Autocomplete Component in Angular | Step-by-Step Guide
- Using Local Storage in Angular Applications: A Practical Guide with Real-Life Examples
- How to Implement reCAPTCHA in an Angular Application: A Step-by-Step Guide
- How to Show a Warning Message to Users When They Try to Close Your Website
- Lazy Loading in Angular: Boosting Performance and User Experience
- Understanding the CanLoad Guard in Angular: Real-time Example
- How to Use Multiple Angular AuthGuards in canActivate | Step-by-Step Guide
- Angular Custom Directives: A Beginner’s Guide with Real-Time Scenario
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.