We have to add an error handling to handle any error on every HttpClient requests. To do that, simply open and edit `src/app/api.service.ts` then add this function that handles the error in a simple way.
private handleError<T>(operation = 'operation', result?: T) {
return (error: any): Observable<T> => {
console.error(error);
this.log(`${operation} failed: ${error.message}`);
return of(result as T);
};
}
private log(message: string) {
console.log(message);
}
In the above codes, we are creating 2 functions for handle error and print log of error. There are the new required modules, so, add it to existing imports.
import { Observable, of } from 'rxjs';
Next, add a HttpClient request function with catchError.
getSmartphone(): Observable<any> {
return this.http.get<Smartphone[]>(localUrl).pipe(
catchError(this.handleError<Smartphone[]>('getSmartphone', [])));
}
Change the get data function in the component to this function.
getSmartphones() {
this.api.getSmartphone()
.subscribe(data => {
console.log(data);
});
}
Another way to handle the error is by using HttpInterceptor. To do that, create a new folder `src/app/interceptors` and an HttpErrorInterceptor file.
mkdir src/app/interceptors
touch src/app/interceptors/HttpErrorInterceptor.ts
Next, open and edit `src/app/interceptors/HttpErrorInterceptor.ts` then add these imports of RxJS Observable, throwError, catchError, tap, Angular Common Http HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, and HttpErrorResponse.
import { catchError, tap } from 'rxjs/internal/operators';
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpErrorResponse } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
Add these Typescript class that intercepts error from the HttpRequest.
@Injectable()
export class HttpErrorInterceptor implements HttpInterceptor {
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request)
.pipe(
tap(data => console.log(data)),
catchError((error: HttpErrorResponse) => {
if (error.error instanceof ErrorEvent) {
// A client-side or network error occurred. Handle it accordingly.
console.error('An error occurred:', error.error.message);
} else {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong,
console.error(
`Backend returned code ${error.status}, ` +
`body was: ${error.error}`);
}
// return an observable with a user-facing error message
return throwError(
'Something bad happened; please try again later.');
})
);
}
}
Next, open and edit `src/app/app.module.ts` then add this import of Angular Common Http HttpInterceptor and HttpErrorInterceptor that previously created.
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { HttpErrorInterceptor } from './interceptors/HttpErrorInterceptor';
Add them to the @NgModule provider's array.
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: HttpErrorInterceptor,
multi: true,
}
],
You can use Retry function to retry the HttpRequest after an error is occurred to make sure the HTTP request is a real error. Add this function after the pipe function inside HttpErrorInterceptor or service function.
getSmartphone(): Observable<any> {
return this.http.get<Smartphone[]>(localUrl).pipe(
retry(3), catchError(this.handleError<Smartphone[]>('getSmartphone', [])));
}
Don't forget to modify existing RxJS import.
import {catchError, retry} from 'rxjs/internal/operators';