jojo
jojo

Reputation: 170

Angular4 how to chain forkJoin with flatMap

I'm in the situation where I need to make 5 http calls that can be executed in parallel + another http call that need to be executed after these five.

I used forkJoin for the first 5, but I don't have any idea how to chain flatMap (or other function).

forkJoin(
      firstObservable,
      secondObservable,
      thirdObservable,
      ..)
      .subscribe(results => {

        this.myComposedObject = results[0];
        let secondResult = results[1];
        let thirdResult = results[2];
        [...]


        // !!! AT THIS POINT I WOULD NEED TO MAKE AN EXTRA CALL!
        // results[1] contains data I need to make the extra call


        // 
        this.myComposedObject.second = secondResult;
        this.myComposedObject.third = thirdResult;
});

I do this operation within a component, so at the end I assign data to myComposedObject.

Upvotes: 2

Views: 6368

Answers (2)

jojo
jojo

Reputation: 170

Thanks, that pointed me to the right direction. I had some problem with results types. When I tried to assign

this.myComposedObject.second = allResults[1];

compiler complains about type conversion, so I'll report my solution here for other people.

In order to get rid of this problem you take advantage of "destructuring" (more info here: https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)

forkJoin(
    firstObservable,
    secondObservable,
    thirdObservable,
    ...
  )
  .concatMap(firstFiveResults => makeAnotherCall(firstFiveResults[1])
    .map(anotherResult => [...firstFiveResults, anotherResult])
  )
  .subscribe((allResults: [
     TypeA, <-- type returned from firstObservable
     TypeB, 
     TypeC, 
     TypeD, 
     TypeE
   ]) => {
    this.myComposedObject.second = allResults[1];
    this.myComposedObject.third = allResults[2];
    // allResults[5] - response from `makeAnotherCall`
    ....
  });

Upvotes: 0

martin
martin

Reputation: 96979

Like you said to make 5 parallel requests you can use forkJoin. Then you want to make another request when the previous 5 complete so you'll chain it with the concatMap operator (or mergeMap would work here as well).

Then you need to work with all the results combined so you can use map to add the last result to the the same array as the previous five.

forkJoin(
    firstObservable,
    secondObservable,
    thirdObservable,
    ...
  )
  .concatMap(firstFiveResults => makeAnotherCall(firstFiveResults[1])
    .map(anotherResult => [...firstFiveResults, anotherResult])
  )
  .subscribe(allResults => {
    this.myComposedObject.second = allResults[1];
    this.myComposedObject.third = allResults[2];
    // allResults[5] - response from `makeAnotherCall`
    ....
  });

Upvotes: 4

Related Questions