How to Use Loading in Interceptor? - Angular 17
Last Updated :
07 May, 2024
In Angular applications, HTTP interceptors are a powerful feature that allows you to intercept and modify HTTP requests and responses. One common use case for interceptors is to display a loading indicator to the user while an HTTP request is in progress. This improves the user experience by providing visual feedback that the application is responding to their actions. In this article, we will explore how to use loading in an interceptor in Angular V17 and provide a brief overview of what interceptors are.
Prerequisites:
What are Interceptors?
Interceptors in Angular are middleware functions that can intercept and modify HTTP requests and responses. They sit between the application's HTTP client (typically the built-in HttpClient module) and the server. Interceptors provide a way to encapsulate cross-cutting concerns related to HTTP communication, such as authentication, logging, caching, error handling, and content transformation.
Interceptors can modify outgoing HTTP requests by adding headers, transforming request bodies, or even cancelling requests altogether. Additionally, they can modify incoming HTTP responses by transforming the response data, handling errors, or adding custom logic based on the response
Steps to implement Loading in Interceptor
Step 1: Create an angular application
We can create an angular 17 application using the angular cli
ng new loader-with-interceptor
cd loader-with-interceptor
This will create a directory named interceptor and change our current directory to the interceptor.
Folder Structure
Folder Structure
Dependencies
"dependencies": {
"@angular/animations": "^17.3.0",
"@angular/common": "^17.3.0",
"@angular/compiler": "^17.3.0",
"@angular/core": "^17.3.0",
"@angular/forms": "^17.3.0",
"@angular/platform-browser": "^17.3.0",
"@angular/platform-browser-dynamic": "^17.3.0",
"@angular/router": "^17.3.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.3"
}
Step 2: Create a progress bar component
This component will be used to show some animation on the UI, so the user knows that something is happening in the background. It can be a progress bar or even an animated bulb like effect. We will use the progress bar service to conditionally render this animation.
We will use the angular cli to create progress bar component,
ng g c progress-bar
Example
HTML
<!-- progress-bar.component.html -->
@if ((progressBarService.isLoading | async) != 0) {
<div class="progress-bar">
<div class="progress-bar-value"></div>
</div>
}
HTML
<!-- app.component.html -->
<app-progress-bar></app-progress-bar>
<button (click)="makeRequest()">
Make Request
</button>
CSS
/* progress-bar.component.scss */
.progress-bar {
height: 4px;
background-color: rgba(5, 114, 206, 0.2);
width: 100%;
overflow: hidden;
}
.progress-bar-value {
width: 100%;
height: 100%;
background-color: rgb(5, 114, 206);
animation: indeterminateAnimation 1s infinite linear;
transform-origin: 0% 50%;
}
@keyframes indeterminateAnimation {
0% {
transform: translateX(0) scaleX(0);
}
40% {
transform: translateX(0) scaleX(0.4);
}
100% {
transform: translateX(100%) scaleX(0.5);
}
}
JavaScript
// progress-bar.component.ts
import { Component } from '@angular/core';
import { ProgressBarService } from './progress-bar.service';
import { AsyncPipe } from '@angular/common';
@Component({
selector: 'app-progress-bar',
standalone: true,
imports: [AsyncPipe],
templateUrl: './progress-bar.component.html',
styleUrl: './progress-bar.component.scss'
})
export class ProgressBarComponent {
constructor(
public progressBarService: ProgressBarService
) { }
}
JavaScript
// progress-bar.service.ts
import { Injectable } from '@angular/core';
import { BehaviorSubject, Subject } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class ProgressBarService {
public concurrentReq = 0;
private _isLoading = new BehaviorSubject<number>(0);
isLoading = this._isLoading.asObservable();
show() {
this._isLoading.next(++this.concurrentReq);
}
hide() {
this._isLoading.next(--this.concurrentReq);
}
}
JavaScript
// app.component.ts
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { ProgressBarComponent } from './progress-bar/progress-bar.component';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterOutlet, ProgressBarComponent],
templateUrl: './app.component.html',
styleUrl: './app.component.scss',
})
export class AppComponent {
title = 'loader-with-interceptor';
constructor(private httpClient: HttpClient) { }
makeRequest() {
this.httpClient
.get('https://jsonplaceholder.typicode.com/todos/1')
.subscribe((res) => {
console.log(res);
});
}
}
JavaScript
// http.interceptor.ts
import {
HttpRequest,
HttpInterceptorFn,
HttpHandlerFn,
} from '@angular/common/http';
import { inject } from '@angular/core';
import { finalize, tap } from 'rxjs/operators';
import { ProgressBarService } from './progress-bar/progress-bar.service';
export const httpInterceptor: HttpInterceptorFn = (
req: HttpRequest<unknown>,
next: HttpHandlerFn
) => {
const progressBarService = inject(ProgressBarService);
progressBarService.show();
return next(req).pipe(finalize(() => progressBarService.hide()));
};
JavaScript
// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { httpInterceptor } from './http.interceptor';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
provideHttpClient(withInterceptors([httpInterceptor])),
]
};
To start the application run the following command.
ng serve
Output:
On clicking the Make Request button we should be able to see the below output
Animated bulb loader
That's cool right? We can also try a classic glowing bulb like animation. We can create another component AnimatedBulbComponent using the angular cli.
ng g c animated-bulb
Add a simple animated bulb in HTML and CSS. We can make their position absolute so they don't interfere with other elements. Also use the same logic as ProgressBarComponent to render them conditionally.
Example:
HTML
<!-- animated-bulb.component.html -->
@if ((progressBarService.isLoading | async) != 0) {
<div class="bulb"></div>
}
HTML
<!-- app.component.html -->
<app-animated-bulb></app-animated-bulb>
<button (click)="makeRequest()">
Make Request
</button>
CSS
/* animated-bulb.component.scss */
.bulb {
width: 20px;
height: 20px;
background-color: yellow;
border-radius: 20px;
position: absolute;
bottom: 4px;
right: 4px;
animation: blink 1s infinite ease-out;
}
@keyframes blink {
0% {
opacity: 1;
}
50% {
opacity: 0.3;
}
100% {
opacity: 1;
}
}
JavaScript
// animated-bulb.component.ts
import { Component } from '@angular/core';
import { ProgressBarService } from '../progress-bar/progress-bar.service';
import { AsyncPipe } from '@angular/common';
@Component({
selector: 'app-animated-bulb',
standalone: true,
imports: [AsyncPipe],
templateUrl: './animated-bulb.component.html',
styleUrl: './animated-bulb.component.scss'
})
export class AnimatedBulbComponent {
constructor(
public progressBarService: ProgressBarService
) { }
}
JavaScript
// app.component.ts
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { ProgressBarComponent } from './progress-bar/progress-bar.component';
import { HttpClient } from '@angular/common/http';
import { AnimatedBulbComponent } from './animated-bulb/animated-bulb.component';
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterOutlet, ProgressBarComponent, AnimatedBulbComponent],
templateUrl: './app.component.html',
styleUrl: './app.component.scss',
})
export class AppComponent {
title = 'loader-with-interceptor';
constructor(private httpClient: HttpClient) { }
makeRequest() {
this.httpClient
.get('https://jsonplaceholder.typicode.com/todos/1')
.subscribe((res) => {
console.log(res);
});
}
}
Output
Similar Reads
How To Use PrimeNG Icon In Angular 17?
PrimeNG is a popular UI component library for Angular applications that provides a wide range of pre-built components, including icons. With Angular 17, PrimeNG icons can be easily integrated into your project. In this article, we'll walk you through how to set up and use PrimeNG icons in your Angul
2 min read
HTTP Interceptors in Angular
In Angular, HTTP interceptors are a powerful feature that allows you to intercept and modify HTTP requests and responses at a centralized location. They act as middleware, sitting between the application's HTTP client (typically the built-in HttpClient module) and the server. What is an HTTP Interce
5 min read
HTTP Interceptor use-cases in Angular
In Angular, HTTP interceptors are a powerful feature that allows you to intercept and modify HTTP requests and responses at a centralized location. They act as middleware, sitting between the applicationâs HTTP client (typically the built-in HttpClient module) and the server. In this article, we wil
7 min read
How to use Angular Material in Angular 17?
Angular Material is a comprehensive UI component library designed specifically for Angular applications. With its large collection of pre-built components and seamless integration with Angular, Angular Material simplifies the process of creating visually appealing and responsive user interfaces. In
2 min read
How To Display Values With Interpolation In Angular?
Angular is a powerful framework for building dynamic web applications. One of its key features is data binding, which allows developers to display and update values seamlessly within the UI. Interpolation is a fundamental technique in Angular that enables the integration of component data directly i
3 min read
How To Use ngx toastr in Angular17 ?
In Angular, we have a styling component called ngx-toastr, widely used for displaying non-blocking notifications to the user. This component helps enhance the user experience by providing feedback for various actions like success, error, info, and warning messages. By integrating ngx-toastr with Ang
3 min read
AngularJS | How to use ng-idle?
The ng-idle is used to decrease the burden, bandwidth, and workload of an app, website, program, or software. With the help of ng-idle log out the session of inactive users so that our precious data & the workload is getting preserved or to even taunt them to participate more actively. The ng-id
3 min read
How To Use @Injectable Decorator In Angular?
In Angular, the @Injectable decorator is used to mark a class as available for dependency injection. This allows Angular to create and manage instances of this class and inject it into other components, services, or other classes. In this article, we will see how to use the @Injectable decorator in
3 min read
String Interpolation in Angular 8
String Interpolation in Angular 8 is a One-way Data-Binding technique that is used to transfer the data from a TypeScript code to an HTML template (view). It uses the template expression in double curly braces to display the data from the component to the view. String interpolation adds the value of
2 min read
How to use $rootScope to store variables in Angular ?
In Angular, the $rootScope is the service that is the top-level for all the controllers in the Angular application. This exists over the entire application lifecycle and can also be used to store the variables that need to be accessed globally. $rootScope is a singleton object that is across the ent
4 min read