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