javascriptrxjsredux-observable

Why we need to return a stream instead of direct dispatch a value?


On workspace, my colleagues told me that i must instead of writing this

import store from './store.ts'

// Epic code
...
mergeMap(data => {
    store.dispatch(someActionCreator(data))
    return EMPTY
})
...

should write something like this

// Epic code
...
mergeMap(data => {
    return of(someActionCreator(data))
})
...

I know that all actions which are written in of rxjs operator will be automatic wrapped in dispatch function and dispatched automatically, but why it is bad to dispatch all actions like in the first example?

Yes, we will not return any stream$, but if its a last iteration in sequence, do we really need to return this stream$ instead of manual dispatch?


Solution

  • It is considered a best-practice to not cause "side-effects" in most operators. Side-effects can be described as statements that modify / mutate state somewhere "outside" of the Operator chain.

    With the dispatch call, you directly cause the mutation of state, which can be considered a side-effect.

    There are many opinions why side-effects should be avoided. I can cite a few:

    By the way, the origin of the whole operator-pattern is functional programming, where a call such as the one you're describing would technically not be possible.

    So I think the answer to your question is mostly opinion-driven. Technically I believe it won't change anything in your use-case. Also, the points made above should be taken with a grain of salt, because you'll always cause side-effects somewhere if you subscribe to e.g. a HTTP API in mergeMap.