Video at https://www.youtube.com/watch?v=ajosuyhcKV4
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 ?
Leave a Reply