Angular - Add loading spinner
Table of Contents
Use Rxjs and Interceptor to show and hide loading spinner in Angular when processing API.
The technique is same as building a lightbox effect Modal.
Implementation
Add service
- Generate service through command
ng g s loading
- loading.service.ts
private _loading = new BehaviorSubject<boolean>(false); public readonly $loading = this._loading.asObservable(); show() { this._loading.next(true); } hide() { this._loading.next(false); }
Add component
Generate component through command
ng g c loading
loading.component.html
- Show the loader only when
loading$
is true. - AsyncPipe (
| async
) use to unwrap a value from an asynchronous primitive. Observable is an asynchronous primitive, it can subscribe and upwrap the value through async pipe.
<div class="backdrop" *ngIf="loading$ | async"> <div class="loader"></div> </div>
- Show the loader only when
loading.component.ts
loading$: Observable<boolean> = this._loadingService.loading$; constructor(private _loadingService: LoadingService) { }
loading.component.scss
.backdrop { position: absolute; top: 0; left: 0; margin: auto; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 20000; .loader { position: absolute; inset: 0; border: 16px solid var(--light); border-top: 16px solid var(--primary); border-radius: 50%; width: 120px; height: 120px; margin: auto; animation: spin 2s linear infinite; } } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
Add Interceptor
Start loading before sending the request and stop loading after the request completed.
- Generate interceptor through command
ng g interceptor network
- network.interceptor.ts
import { LoadingService } from './loading.service'; import { finalize } from 'rxjs/operators'; constructor(private _loadingService: LoadingService) {} intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> { this._loadingService.show(); return next.handle(request).pipe( finalize(() => this._loadingService.hide()) ); }
- app.modules.ts
providers: [{ provide: HTTP_INTERCEPTORS, useClass: NetworkInterceptor, multi: true }],
Build a popup modal
The implementation we had just done is similar to lightbox effect. We can also apply methods above to build a modal.

References
Add an Angular Loading Spinner with RxJS and Material