Dispatch multiple actions from in redux-observable

Viewed 1563

I am trying to dispatch multiple actions to redux. Here is my code

 action$.pipe(
    ofType(trigger),
    mergeMap(({ payload }) =>
      from(endpoint(payload)).pipe(
        map(response =>

          // this works fine
          // setData(response.data)

          // this doesn't
          concat(
            of(setData(response.data)),
            of({ type: 'hello' })
          )

          // I also tried
          [
            of(setData(response.data)),
            of({ type: 'hello' })
          ]

        )
      )
    ),

    catchError(err => Promise.resolve(creators.setError(err)))
  )

Single dispatch works, but if I try multiple items as above I am getting Uncaught Error: Actions must be plain objects. Use custom middleware for async actions.

1 Answers

map just maps one item to another so when you return [action1, action2] you're still returning an array and redux-observable tries to treat it as an action itself. What you want instead is "unwrapping" the array (or Observable created with concat) returned.

So instead of using map you can use mergeMap (or concatMap) and when you return an array it'll iterate it and make separate emissions for each item:

mergeMap(response => [
  setData(response.data),
  { type: 'hello' },
]),

If this looks too odd you can wrap the array with from to make it more obvious:

mergeMap(response => from([
  setData(response.data),
  { type: 'hello' },
])),

You can even use a single of:

mergeMap(response => of(
  setData(response.data),
  { type: 'hello' },
)),
Related