0
votes

I am trying to return 2 separate values from an epic given a single source$ action. However - it seems I can only do this by explicitly subscribing to the inner Observable. My epic currently looks like this:

export const orderItemEpic = action$ =>
  action$.ofType(ORDER_ITEM)
    .switchMap(action => Observable.of(
        api.createOrder(action.payload.order),
        api.updateItem(action.payload.item, action.payload.item._id)
    ))
    .map(val => console.log('Outer Observable', val));

However this only emits the promise of the first api request (even though both are called)

The only way I can get the two values simultaneously is to subscribe explicitly to the inner Observable Like so:

export const orderItemEpic = action$ =>
  action$.ofType(ORDER_ITEM)
    .switchMap(action => Observable.of(
        api.createOrder(action.payload.order),
        api.updateItem(action.payload.item, action.payload.item._id)
    ).map(val => val).subscribe(v => console.log('Inner Observable', v))
    .map(val => console.log('Outer Observable', val)); //never gets called

But now my 'Outer' Observable does not get mapped.

When I mock this with JSBin it seems the first example should emit the response from both api calls. http://jsbin.com/cejolegixo/edit?js,console

I guess I'm just wondering if this is some quirk in redux-observable or if I am doing something incorrect.

Thanks

1

1 Answers

0
votes

It's because you have 3 levels of Observable going on.

this only emits the promise of the first api request

Your JSBin more accurately mirrors the code if you use

// First Mock API
const firstAPI = res => Rx.Observable.of({...res})

// Second Mock API
const secondAPI = res => Rx.Observable.of({...res})

So, the fix is to 'merge' the inner observables.

// map value from source into inner observable, when complete emit result and move to next
const stream = source$.switchMap(action => Rx.Observable.merge(
  firstAPI(action.payload.a),
  secondAPI(action.payload.b)
))

Ref JSBin

BTW, you can flatMap instead of switchMap. Depends on the behaviour you want.

switchMap will cancel a first order when a second arrives while the first is progress (seems bad if they are different orders).