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, ]
Leave a Reply