Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a sequence of http requests in Angular 6 using RxJS

I've been looking for a solution all over the web, but couldn't find anything that fits my user case. I'm using the MEAN stack (Angular 6) and I have a registration form. I'm looking for a way to execute multiple HTTP calls to the API and each one is dependent on the returned result from the previous one. I need something that looks like this:

firstPOSTCallToAPI('url', data).pipe(
    result1 => secondPOSTCallToAPI('url', result1)
    result2 => thirdPOSTCallToAPI('url', result2)
    result3 => fourthPOSTCallToAPI('url', result3)
    ....
).subscribe(
    success => { /* display success msg */ },
    errorData => { /* display error msg */ }
);

What combination of RxJS operators do I need to use to achieve this? One possible solution would be to nest multiple subscriptions, but I want to avoid that and do it better with RxJS. Also need to think about error handling.

like image 870
Andi Aleksandrov Avatar asked Nov 30 '18 15:11

Andi Aleksandrov


People also ask

Which method is used in RXJS to work on multiple operator together in sequential order?

ConcatAll This operator combines all emitted inner streams and just as with plain concat sequentially produces values from each stream.

What is concatMap in RXJS?

concatMap operator is basically a combination of two operators - concat and map. The map part lets you map a value from a source observable to an observable stream. Those streams are often referred to as inner streams.

What is the use of RXJS in Angular 6?

RxJS is a popular library among web developers. It provides functional and reactive programming patterns for working with events and streams of data and has been integrated into many web development libraries and frameworks such as Angular.


2 Answers

For calls that depend on previous result you should use concatMap

firstPOSTCallToAPI('url', data).pipe(
    concatMap(result1 => secondPOSTCallToAPI('url', result1))
      concatMap( result2 => thirdPOSTCallToAPI('url', result2))
       concatMap(result3 => fourthPOSTCallToAPI('url', result3))
    ....
).subscribe(
    success => { /* display success msg */ },
    errorData => { /* display error msg */ }
);

if your async method does not depend on return value of the precedent async call you can use

   concat(method(),method2(),method3()).subscribe(console.log)
like image 197
Fan Cheung Avatar answered Oct 12 '22 17:10

Fan Cheung


MergeMap

is exact what you are looking for

firstPOSTCallToAPI('url', data).pipe(
    mergeMap(result1 => secondPOSTCallToAPI('url', result1)),
    mergeMap(result2 => thirdPOSTCallToAPI('url', result2)),
    mergeMap(result3 => fourthPOSTCallToAPI('url', result3)),
    // ...
).subscribe(
    success => { 
      // here you will get response of LAST request (fourthPOSTCallToAPI)
    },
    errorData => { /* display error msg */ }
);


// I assume that
// secondPOSTCallToAPI, thirdPOSTCallToAPI and fourthPOSTCallToAPI
// returns obserwable eg. return this.http.get<Book>(apiUrl);
like image 28
Kamil Kiełczewski Avatar answered Oct 12 '22 18:10

Kamil Kiełczewski