H2 — Angular HTTP in Depth : Retry Failed, Set Http Headers

Sourabhh Sethii
DXSYS
Published in
5 min readJun 21, 2020

We welcome you all to the second article of this series Angular HTTP in Depth. Here we will be looking in Retry Failed HTTP Cases along with setting and reading custom HTTP Headers using HttpClientModule.

When the connection with the backend fails, before giving the user a negative response, it might be worth trying to automatically recover from the error. In some cases, that can be as simple as retrying to issue the request again.

The Angular HttpClient works well with RxJS we can apply some of its operators to make this happen, such as retry, retryWhen and delay.

So here we have a simple app component, which internally gets account service injected. Here we have a sendAccountDetailsPostParamsHandled function, which gets triggered whenever someone clicks that button here which then invokes on the account service that fetch people function. Internally here, we can see that an HTTP call gets made with that HTTP client, which comes from the Angular common HTTP package.

As you can see here, I on purpose commanded out here a working URL and replaced it with one which fails. So whenever I click the button, we can see we get a 404 status code and some error message gets printed out here.

Lets look into the example given below

sendAccountDetailsPostParamsHandled(): Observable<Object> {const newAccount = {name: 'Sourabh'};return this.http.post('/assets/data/account.json?', newAccount)// tslint:disable-next-line: align.pipe(retryWhen(err => {let retires = 3;return err.pipe(delay(1000))// tslint:disable-next-line: no-shadowed-variable.pipe(mergeMap((err: any) => {if ( retires-- > 0){return   of(err);// tslint:disable-next-line: align} else {return throwError(err);}}));}));}

So what we could try instead is to simply introduce a delay, so only retry it after you’ve maybe an incrementing amount of time. Instead of the retry operator, we could use the retry when operator which gives us here a parameter. Then here we can specify the number of retries, which let’s say is three, and then return here the observable to not interrupt the chain.

We introduce here a delay, let’s say one second just to make it more visible. Then we again get here merge Map and say whenever that retries when its minus is bigger than zero, we return the observable of that value. So we simply continue basically that chain, the repetitions. We’re never below our retries. So when retries are finished, we say observable.throw of that value, because we want to throw the error and interrupt that repetition chain.

Now we need to add some imports here for RXJS.

import { retryWhen, delay } from ‘rxjs/operators’;

import { of, throwError } from ‘rxjs’;

import {mergeMap} from ‘rxjs/operators’;

Set Metadata in HTTP Headers with Angular HttpHeaders

In this section we learn how to leverage Angular’s HttpClient to set such headers.

Now in many cases, we also need to send some HTTP header. For instance, if we inspect here the call that gets made, we can see that there is a header section. Basically here, we have the general effect where the URL is displayed. Then we have the response headers which come back from the server.

We are especially interested here in the request headers, which get sent to the server. One simple example could be to submit, for instance, the current language of the user. With the new HTTP client, which here it resides in the Angular common HTTP package, this is quite easy.

We can simply here pass a second parameter. Now we need to import here the HTTP header type, and then on the object here, we can specify the headers property, instantiate here a new HTTP headers object, and set the header which we want.

import { HttpClient, HttpParams, HttpHeaders, HttpResponse } from '@angular/common/http';

For instance, let’s call this app language. As a value, I pass simply a string, which is in this case is Anguar.

Now if this header is something you want to send for each request that is being executed against the server, you might think of moving this part here into an interceptor.

fetchAccount(): Observable<Object> {return this.http.get('/assets/data/account.json', {headers : new HttpHeaders().set('Language', 'Angular')});}

Read Custom HTTP Headers Sent by the Server in Angular

What if we are interested in actually some custom headers which our response gives us back? For instance, in this example here, in the response headers here after we request, you can see there is the my custom header. I would like to read that header out.

In order to do so, I have to change basically the call here because the account itself only contains the raw data coming from the response body. I’m interested also in the header values in this case. To do so, we can specify here so-called observe value.

sendAccountDetails(): Observable<HttpResponse<Object>> {return this.http.get('/assets/data/account.json?queryparamTest=123',{ observe : 'response'});}

The observe value specifies what we are currently interested in observing and therefore also changes here the response type of our HTTP request. We could have here different kind of values, for instance, events when you are interested in HTTP events. We would get here an observable of an HTTP event.

In our case, we are interested in the response specifically. According to here we get now an HTTP response of type account . We need to import that from the common HTTP package. We can now go to our app component here. Let’s Console log what comes back from data.

If I execute request, you can see now we have a series of properties here which is our response object actually that gets printed here out on our UI. Now, to retrieve our custom header, what we can do here is to access the header property. Then we use the get method and specify here my custom header which is the header name I specified on the server side.

Again, executing here the request and then looking here in response headers, I can see that my custom header gets back again. Here also now on the Console, we get Angular rocks printed out which is actually the value of that my custom header.

sendDetails(){this.accounts = this.accoutService.sendAccountDetails().subscribe((data) => {console.log(data);this.response = data;this.accounts = data.body;this.message = '';});}

Reference Code is available below.

--

--

Sourabhh Sethii
DXSYS
Editor for

I am an author of Building Digital Experience Platform and I am passionate about emerging technologies. https://sourabhhsethii.com/