Tony Smith
Tony Smith

Reputation: 899

How do you return combineLatest results along with switchMap values?

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

Answers (2)

nilsandrey
nilsandrey

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

shenghua lian
shenghua lian

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

Related Questions