I'm looking for way of dispatching multiple redux actions in a single Epic of redux-observable
middleware.
Let's assume I have following Epic. Everytime when SEARCH
event happens, Epic loads data from backend and dispatches RESULTS_LOADED
action.
searchEpic = (action$) => action$ .ofType('SEARCH') .mergeMap( Observable .fromPromise(searchPromise) .map((data) => { return { type: 'RESULTS_LOADED', results: data } }) )
Now, let's assume that I need dispatch additional action when the searchPromise
is resolved.
The simplest way of doing so seems to have a second epic that will listen to RESULTS_LOADED
and dispatch the second action. Like so:
resultsLoadedEpic = (action$) => action$ .ofType('RESULTS_LOADED') .map(({results} => { return { type: 'MY_OTHER_ACTION', results } })
In this simple example it's quite easy. But when Epics grow, I tend to find myself having a lot of redux actions which sole purpose is to trigger other actions. Additionally, some of the rxjs code needs to be repeated. I find this a bit ugly.
So, my question: Is there a way to dispatch multiple redux actions in a single Epic?
There is no requirement that you make a one-to-one in/out ratio. So you can emit multiple actions using mergeMap
(aka flatMap
) if you need to:
const loaded = (results) => ({type: 'RESULTS_LOADED', results}); const otherAction = (results) => ({type: 'MY_OTHER_ACTION', results}); searchEpic = (action$) => action$ .ofType('SEARCH') .mergeMap( Observable .fromPromise(searchPromise) // Flattens this into two events on every search .mergeMap((data) => Observable.of( loaded(data), otherAction(data)) )) )
Note that any Rx operator that accepts an Observable also can accept a Promise, Array, or Iterable; consuming them as-if they were streams. So we could use an array instead for the same effect:
.mergeMap((data) => [loaded(data), otherAction(data)])
Which one you use depends on your personal style preferences and use case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With