Interceptor in Angular–Error service

Similar video at https://www.youtube.com/watch?v=ajosuyhcKV4

I need to inform the user when the application is loading data with error ( i.e. the backend is giving some error back). And do it seamlessly , every time.

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

Also, I have the need to display this no matter in what page  – so a service will help


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

@Injectable({
  providedIn: 'root'
})
export class ErrorService {

  private err: Subject<string>;

  constructor() {
    this.err = new Subject<string>();
  }

  public NextError(): Observable<string> {

    return this.err.asObservable();

  }

  public setNextError(str: string) {

    this.err.next(str);

  }

}


Now the interceptor

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

import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { ErrorService } from './error.service';

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


  constructor(private err: ErrorService ) {


  }
  intercept(req: HttpRequest<any>, next: HttpHandler):
    Observable<HttpEvent<any>> {

    return next.handle(req).pipe(
        catchError( err => this.handleError(req, err))
    );
  }

  private handleError(req: HttpRequest<any>, error: HttpErrorResponse) {
    if (error.error instanceof ErrorEvent) {
      // A client-side or network error occurred. Handle it accordingly.
      const str = 'An error occurred:' +   error.error.message;
      console.log(str);
      this.err.setNextError(str);

    } else {
      // The backend returned an unsuccessful response code.
      // The response body may contain clues as to what went wrong,
      const str =
        `Backend returned code ${error.status}, ` +
        `body was: ${JSON.stringify(error.error)}`;
      console.log(str);
      this.err.setNextError(str);
    }
    // return an observable with a user-facing error message
    return throwError(
      'Something bad happened; please try again later.');
  }
}


The class itself

@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);

  }

And this is all !( besides registering the interceptors in a barrelInterceptors.ts

import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { ErrorInterceptor } from './ErrorInterceptor';
import { LoaderInterceptor } from './LoaderInterceptor';





/** Http interceptor providers in outside-in order */
export const httpInterceptorProviders = [
  { provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true },
  { provide: HTTP_INTERCEPTORS, useClass: LoaderInterceptor, multi: true },
];

and register to the appmodule.ts


providers: [
    httpInterceptorProviders,
  ]