Update
Here is a working example using redux-observable. https://redux-observable-playground-ykzsyp.stackblitz.io This achieves what I want using mergeMap and if/else statement, but I was hoping to use Observable.filter
as that seems more elegant.
Original question
I have an epic that currently dispatches a single action but would like to dispatch different actions based on a filter using a single stream. Here is the current code:
const streamEpic = (action$) => action$.pipe(
ofType('START_PLAYBACK_STREAM'),
switchMap(playbackStream$),
filter((playEvent) => playEvent.type === 'LOAD')),
map((playEvent) => loadActionCreator(playEvent.fileName))
// how can I filter on other types?
// and dispatch other actions?
);
I've seen many rxjs examples that use a single stream and filter to map different actions, for example:
playbackStream$
.filter((playEvent) => playEvent.type === 'LOAD'))
.map((playEvent) => loadActionCreator(playEvent.fileName));
playbackStream$
.filter((playEvent) => playEvent.type === 'START'))
.map((playEvent) => startActionCreator());
playbackStream$
.filter((playEvent) => playEvent.type === 'STOP'))
.map((playEvent) => stopActionCreator());
I'm trying to do this same thing in redux-observable but no luck. If I use tap, ignoreElements, and store.dispatch I can get the following to work but I know its an anti-pattern.
const streamLoadEvents = (action$, store) => action$.pipe(
ofType('START_PLAYBACK_STREAM'),
tap(() => {
playbackStream$
.filter((playEvent) => playEvent.type === 'LOAD'))
.map((playEvent) => store.dispatch(loadActionCreator(playEvent.fileName)));
playbackStream$
.filter((playEvent) => playEvent.type === 'START'))
.map((playEvent) => store.dispatch(startActionCreator()));
playbackStream$
.filter((playEvent) => playEvent.type === 'STOP'))
.map((playEvent) => store.dispatch(stopActionCreator()));
}),
ignoreElements()
);
I know that I could also use a switch or if/else statement inside of something like map or switchMap, like the answer here: Redux-Observable multiple actions in single epic, but I'd like to avoid this as its rather inelegant and does not take full advantage of streaming operators. The answer here: https://stackoverflow.com/a/40895613/367766 seems to get me a little closer...
What's the suggested approach here? Are the operators or example you can point me to? Thanks!
Observable.filter
as it seemed to be more elegant. Here is a playground with a working example: redux-observable-playground-ykzsyp.stackblitz.io – user367766