Angular Handling Global Error to Try Again
Handling Exceptions Using the Angular HttpClient Service
Introduction
HTTP requests are extremely fault-decumbent because there are generally a lot of unknowns surrounding them. Is the server y'all are trying to reach running properly? Is the API returning the payload you are expecting? In this guide, you will learn what to do when these questions are not answered in the appropriate way. We volition discuss some of the all-time ways to manage HTTP exceptions within your app while using Angular's HttpClient service.
Getting Started Treatment HTTP Exceptions
When talking about handling HTTP exceptions in Athwart, it is nearly impossible not to talk nearly RxJs. The Angular framework is heavily bought into the RxJs library—a library that brings reactive programming into the JavaScript ecosystem. Angular's own HttpClient makes use of RxJs under the hood to ensure that the client has an observable API.
There are a few RxJs operators which you will need to be familiar with in society to handle exceptions properly. The principal operators we will business organisation ourselves with in this guide are the catchError
and throwError
operators.
Catching HTTP Exceptions
Using the catchError
operator gives you the power to catch errors that may occur within an observable stream. Let's cheque out how nosotros can use this operator in an example app.
Here is an example service for fetching books from the server. It looks like this:
1 import { HttpClient } from '@angular/mutual/http' ; two import { Injectable } from '@angular/core' ; iii import { Book } from 'app/models/book' ; 4 5 @ Injectable ( ) 6 export class BooksService { 7 private booksApiUrl = '/api/books' ; viii 9 constructor ( private http : HttpClient ) { } 10 11 getBooks ( ) : Observable < Book [ ] > { 12 render this . http . get ( this . booksApiUrl ) ; 13 } 14 }
typescript
And here is an example component that uses BooksService
:
ane import { Component } from '@angular/core' ; 2 import { BooksService } from 'app/services/books' ; 3 import { Book } from 'app/models/book' ; 4 v @ Component ( { 6 selector : 'app-books' , 7 template : ` 8 <ul *ngFor="let book of books$"> 9 <li>{{ book.title }}</li> x </ul> 11 ` 12 } ) thirteen consign class BooksComponent { 14 books$ : Observable < Book [ ] > ; 15 16 constructor ( private booksService : BooksService ) { 17 this . books$ = this . booksService . getBooks ( ) ; 18 } nineteen }
typescript
Above, the BooksComponent
communicates with BooksService
in guild to fetch a payload of books from the server. What if something goes wrong during this request? Of course, you will need to handle this exception in some way.
Adjacent, add together the catchError
operator to BooksComponent
to handle exceptions:
1 import { Component } from '@angular/cadre' ; 2 import { BooksService } from 'app/services/books' ; 3 import { Book } from 'app/models/book' ; 4 import { catchError } from 'rxjs/operators' ; five import { of } from 'rxjs' ; vi 7 @ Component ( { 8 selector : 'app-books' , ix template : ` 10 <error-alert *ngIf="errorMsg" [msg]="errorMsg"></error-alert> 11 <ul *ngFor="let book of books$"> 12 <li>{{ book.title }}</li> 13 </ul> xiv ` xv } ) 16 consign form BooksComponent { 17 books$ : Observable < Book [ ] > ; eighteen errorMsg : string ; nineteen 20 constructor ( private booksService : BooksService ) { 21 this . books$ = 22 this . booksService 23 . getBooks ( ) 24 . pipage ( 25 catchError ( mistake => { 26 if ( error . error instanceof ErrorEvent ) { 27 this . errorMsg = ` Error: ${ error . error . message } ` ; 28 } else { 29 this . errorMsg = ` Error: ${ mistake . message } ` ; 30 } 31 return of ( [ ] ) ; 32 } ) 33 ) ; 34 } 35 }
typescript
You have altered BooksComponent
to catch any exceptions that may occur from the HTTP request! You are also using the of
observable helper part to ensure that when an fault occurs, the appreciable returns an empty assortment. Now, when an fault occurs, the user can easily meet the message.
But what if you want a little more custom command over the error message that is shown? In the next department, yous will larn how y'all can employ the throwError
operator to do just that.
Re-throwing HTTP Exceptions
Odds are, y'all don't want to show the user the exact fault message that yous become from Angular HttpClient when an exception occurs. A great mode to customize this bulletin is by throwing your own custom exceptions using throwError
. First, update your BooksService
to throw a custom error depending on the final condition of the HTTP request.
1 import { HttpClient , HttpErrorResponse } from '@athwart/common/http' ; 2 import { Injectable } from '@angular/cadre' ; 3 import { Volume } from 'app/models/volume' ; 4 import { catchError , throwError } from 'rxjs/operators' ; 5 vi @ Injectable ( ) 7 export class BooksService { 8 private booksApiUrl = '/api/books' ; 9 10 constructor ( private http : HttpClient ) { } xi 12 getBooks ( ) : Observable < Volume [ ] > { 13 return this . http xiv . get ( this . booksApiUrl ) 15 . pipe ( 16 catchError ( fault => { 17 permit errorMsg : string ; 18 if ( fault . error instanceof ErrorEvent ) { 19 this . errorMsg = ` Error: ${ mistake . fault . message } ` ; 20 } else { 21 this . errorMsg = this . getServerErrorMessage ( fault ) ; 22 } 23 24 return throwError ( errorMsg ) ; 25 } ) 26 ) ; 27 } 28 29 private getServerErrorMessage ( error : HttpErrorResponse ) : string { 30 switch ( error . condition ) { 31 case 404 : { 32 return ` Not Institute: ${ error . message } ` ; 33 } 34 case 403 : { 35 return ` Access Denied: ${ error . bulletin } ` ; 36 } 37 case 500 : { 38 return ` Internal Server Error: ${ mistake . bulletin } ` ; 39 } 40 default : { 41 return ` Unknown Server Error: ${ error . message } ` ; 42 } 43 44 } 45 } 46 }
typescript
The above code moved some of the error-handling logic from BooksComponent
to the service. Through the use of both the throwError
operator and the new getServerErrorMessage
method, you lot are now throwing a custom fault from service for HTTP errors.
Now, simplify your BooksComponent
.
one import { Component } from '@athwart/core' ; two import { BooksService } from 'app/services/books' ; 3 import { Book } from 'app/models/book' ; iv import { catchError } from 'rxjs/operators' ; 5 import { of } from 'rxjs' ; 6 7 @ Component ( { eight selector : 'app-books' , nine template : ` ten <error-warning *ngIf="errorMsg" [msg]="errorMsg"></error-alert> 11 <ul *ngFor="let volume of books$"> 12 <li>{{ volume.title }}</li> 13 </ul> xiv ` 15 } ) 16 export class BooksComponent { 17 books$ : Observable < Volume [ ] > ; 18 errorMsg : cord ; 19 20 constructor ( private booksService : BooksService ) { 21 this . books$ = 22 this . booksService 23 . getBooks ( ) 24 . pipage ( 25 catchError ( mistake => { 26 this . errorMsg = error . bulletin ; 27 return of ( [ ] ) ; 28 } ) 29 ) ; thirty } 31 32 }
typescript
It is a best exercise to keep components every bit simple every bit possible. In this example, you have been able to accordingly motility the logic of your error handling from BooksComponent
to BooksService
.
Decision
In this guide, you learned how to manage HTTP exceptions inside your app. You lot accept seen how the RxJs catchError
operator tin be used to take hold of any HTTP exceptions that occur while using the Angular HttpClientservice. You have also seen how to throw your own errors intentionally or re-throw caught errors using the RxJs throwError
operator. By using these 2 techniques, you lot are well equipped to handle unexpected errors inside any HTTP-driven application.
Source: https://www.pluralsight.com/guides/handling-exceptions-using-the-angular-httpclient
0 Response to "Angular Handling Global Error to Try Again"
Post a Comment