Amarnath
Amarnath

Reputation: 8865

Angular + RxJS: Make multiple Server calls within flatMap and retrieve them in subscribe

Below is the code snippet of my problem.

this.locationService.getUserLocation()
    .flatMap(location => {
        // Some code
        return this.searchService.getResults(location); // returns an observable
    })
    .flatMap(searchResponse => {
        // some code  
        // NEED ANOTHER CALL with searchResponse.  --- (A)
        return this.resultsService.getCount(searchResponse.results); --- (B)
    })
    .subscribe(count => {
        console.log(count);
    });

Now I need to make one more call in the second flatMap block. How can I handle this?

If I make multiple Calls how can I subscribe multiple results and retrieve the data in subscribe?

P.S: A and B calls can be done parallely. They just need searchResponse as input.

Upvotes: 2

Views: 3049

Answers (1)

Krypt1
Krypt1

Reputation: 1066

You can use Observable.forkJoin, which will make the calls in parallel and return once all of the inner observables are completed:

this.locationService.getUserLocation()
    .flatMap(location => {
        // Some code
        return this.searchService.getResults(location); // returns an observable
    })
    .flatMap(searchResponse => {
        return Observable.forkJoin(
          this.resultsService.getCount(searchResponse.results),
          Observable.of(searchResponse) // replace with second call here
        );
    })
    .subscribe(([count, results]) => { // forkJoin returns array of results
        console.log(count, results);
    });

Here's more info on the forkJoin operator: Docs


UPDATE

As @ChauTran noticed in comments, if your one or more of the observables do not complete (or you need to get the results before they are completed), then you can use Observable.combineLatest (Docs).

This operator returns as soon as each of the inner observables emits at least once. Here's an example with combineLatest:

this.locationService.getUserLocation()
    //...
    .flatMap(searchResponse => {
        return Observable.combineLatest(
          this.resultsService.getCount(searchResponse.results),
          Observable.of(searchResponse) // replace with second call here
        );
    })
    .subscribe(([count, results]) => { // forkJoin returns array of results
        console.log(count, results);
    });

Upvotes: 2

Related Questions