Interceptor in Angular–loader and service

I need to inform the user when the application is loading data – and when it is not loading anymore. Usually , the data comes from a backend via an HTTP call– and will be some timeout before it becomes available. So – simple – just intercept this and then show some spinning to the user, right ?

I found the documentation about interceptors at https://angular.io/api/common/http/HttpInterceptor – and you can find more searching on google /  bing .

Also, my inspiration was started from here:

https://grensesnittet.computas.com/loading-status-in-angular-done-right/

But , if we intercept, how to distribute ? The services singleton in Angular will provide help

import { Injectable } from '@angular/core';
import { Subject, Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class LoaderService {
  constructor() {
    this.s = new Subject<boolean>();

  }

  public s: Subject<boolean>;
  public loading$(): Observable<boolean> {
    return this.s.asObservable();
  } 

  public isLoading(b: boolean) {
    this.s.next(b);
  }

}

So I have created the HttpInterceptor to call the service , like here:

import { Injectable } from '@angular/core';
import {
  HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpErrorResponse
} from '@angular/common/http';

import { Observable, throwError } from 'rxjs';
import { catchError, tap, finalize } from 'rxjs/operators';

import { LoaderService } from './loader.service';

/** Pass untouched request through to the next request handler. */
@Injectable()
export class LoaderInterceptor implements HttpInterceptor {

  private requests: HttpRequest<any>[] = [];
  constructor(private ls: LoaderService ) {


  }
  removeRequest(req: HttpRequest<any>) {
    const i = this.requests.indexOf(req);
    if (i >= 0) {
      this.requests.splice(i, 1);
    }
    this.ls.isLoading(this.requests.length > 0);
  }
  // https://grensesnittet.computas.com/loading-status-in-angular-done-right/
  intercept(req: HttpRequest<any>, next: HttpHandler):
    Observable<HttpEvent<any>> {
    this.requests.push(req);
    this.ls.isLoading(true);
    return next.handle(req).pipe(
        finalize(() => this.removeRequest(req))
    );
  }

}

And now it is simple to display in any page: – in the HTML

<mat-spinner *ngIf="isLoading"></mat-spinner>

 
and in the .ts pass in the constructor via DI

@Component({
  selector: 'app-covid-navig',
  templateUrl: './covid-navig.component.html',
  styleUrls: ['./covid-navig.component.css']
})
export class CovidNavigComponent  {
  public isLoading = false;
  constructor(private breakpointObserver: BreakpointObserver
    ,         private err: ErrorService
    ,         private snackBar: MatSnackBar
    ,         private ls: LoaderService) {
    this.err.NextError().pipe(
      tap(it => {
        this.snackBar.open(it, 'ERROR', {
          duration: 5000,
        });
      }),
      shareReplay()
    ).subscribe();
    this.ls.loading$().subscribe(it => this.isLoading = it);

  }

Simple , right ?