3
votes

Maybe I'm thinking about this wrong, but a common pattern I use with redux-thunk is to return a promise so I can perform some additional actions in the container object when something completes or fails.


Using Thunk as an example:

Action Creator:

const action = ({ data }) => (dispatch) => 
    fetch(`some http url`)
    .then(response => {
        if(response.ok) {
             return response.json();
        }

        return Promise.reject(response);
    })

Somewhere in the connected component:

this.props.action("Some Data")
    .then(console.log)
    .catch(error => console.error("ERROR"));

Is there a clean way of doing something similar in Redux-Observable/Rxjs? Basically returning a promise from an action, calling an epic, that returns resolve or reject once the observable is complete.

1

1 Answers

8
votes

Generally speaking, I try to shy people away from these patterns when using things like redux-observable/redux-saga. Instead, if you're waiting for an action you dispatched to update the store's state, rely on that state update itself or some sort of transactional metadata your reducers store in the state about it. e.g. { transactions: { "123": { isPending: true, error: null } }

However, if you really do want to do it, you can write (or use an existing) middleware that returns a Promise from dispatch that will resolve when some other specified action has been dispatched (presumably by your epics). redux-wait-for-action is one example (not a recommendation, though cause I haven't used any)

Keep in mind that Promises are not normally cancellable, so you could accidentally create a situation where a component starts waiting for an action, the user leaves that page and the component is unmounted, and you're still waiting for that other action--which can cause weirdness later, like if they come back to that page, etc.


If you're waiting to chain side effects, that belongs in your epics. Kick off a single action that an epic listens for, makes the side effect, then it emits another action to signal completion. Another epic listens for that completion action and then begins the other side effect, etc. You could put them all in a single monolithic epic, if you want, but I find the separation easier for testing and reuse.