How to chain Http calls in Angular2?

You can do this using the mergeMap operator.

Angular 4.3+ (using HttpClientModule) and RxJS 6+

import { mergeMap } from 'rxjs/operators';

this.http.get('./customer.json').pipe(
  mergeMap(customer => this.http.get(customer.contractUrl))
).subscribe(res => this.contract = res);

Angular < 4.3 (using HttpModule) and RxJS < 5.5

Import the operators map and mergeMap, then you can chain two calls as follows:

import 'rxjs/add/operator/map'; 
import 'rxjs/add/operator/mergeMap';

this.http.get('./customer.json')
  .map((res: Response) => res.json())
  .mergeMap(customer => this.http.get(customer.contractUrl))
  .map((res: Response) => res.json())
  .subscribe(res => this.contract = res);

Some more details here: http://www.syntaxsuccess.com/viewarticle/angular-2.0-and-http

More information about the mergeMap operator can be found here


Using rxjs to do the job is a pretty good solution. Is it easy to read ? I don't know.

An alternative way to do this and more readable (in my opinion) is to use await/async.

Example :

async getContrat(){
    //get the customer
    const customer = await this.http.get('./customer.json').toPromise();

    //get the contract from url
    const contract = await this.http.get(customer.contractUrl).toPromise();

    return contract; // you can return what you want here
}

Then call it :)

this.myService.getContrat().then( (contract) => {
  // do what you want
});

or in an async function

const contract = await this.myService.getContrat();

You can also use try/catch to manage error :

let customer;
try {
  customer = await this.http.get('./customer.json').toPromise();
}catch(err){
   console.log('Something went wrong will trying to get customer');
   throw err; // propagate the error
   //customer = {};  //it's a possible case
}

Tags:

Http

Angular