Reputation: 899
This is basically what I am after. Just not sure the best way to return the combination of all three in the switchmap.
unsubscribes = combineLatest(
apiCall1,
apiCall12,
).pipe(
switchMap(([apiCall1Res, apiCall2Res]) => {
return apiCall3(apiCall1Res.Id)
})
).subscribe(([apiCall1Res, apiCall2Res, apiCall3Res]) => {
///Do work
})
Upvotes: 2
Views: 3913
Reputation: 1090
The sequence is correct, you just need to adjust how you treat the return values. When you use switchMap
you transform the output of the observable sequence from the type you are receiving to the type of output of the observable you provide on the switchMap
return. So you just must create an observable that returns the 3 values. You can do it by mapping the flow of the apiCall3 joining with the other two.
I propose one solution that can be adjusted to match your specific scenario if you need more. I created mock objects in order to make the sample directly executable for testing.
You can see the sample running with mock objects on the following stackblitz I created for you:
import { combineLatest, of, timer } from 'rxjs';
import { map, switchMap, tap } from 'rxjs/operators';
// Mock objects...
const apiCall1 = timer(1).pipe(map(() => ({id: 1})));
const apiCall2 = timer(2).pipe(map(() => 2));
// apiCall3 mock created bellow on the fly...
let r1, r2; // <-- to save partial results because they are cutted from the flow bellow...
const source =
combineLatest(
apiCall1,
apiCall2,
).pipe(
tap(([apiCall1Res, apiCall2Res]) => { r1 = apiCall1Res; r2 = apiCall2Res;}),
map(([apiCall1Res, apiCall2Res]) => apiCall1Res.id), // adjust flow to apiCall3
switchMap((apiCall1ResId) => of(apiCall1ResId).pipe(map(id => id+2))), // <-- apiCall3 mock on the fly
map(apiCall3Res => [r1, r2, apiCall3Res])
);
source.subscribe(console.log);
As you can check on the output you receive the 3 values at the subscription observer code.
Upvotes: 1
Reputation: 149
If apiCall3 should after 1 and 2:
combineLatest(
apiCall1,
apiCall12,
).pipe(
switchMap(([apiCall1Res, apiCall2Res]) => {
return apiCall3(apiCall1Res.Id)
.pipe(map(apiCall3Res => [apiCall1Res, apiCall2Res, apiCall3Res]));
})
With ... you can save some space here:
combineLatest(
apiCall1,
apiCall12,
).pipe(
switchMap(results => apiCall3(apiCall1Res.Id)
.pipe(map(apicallResult3 => [...result, apicallResult3])
)
)
Upvotes: 5