In order for me to set the Composition, I have to get the Output object first.
I'm trying to copy the examples and I feel like I'm copying the syntax correctly but I keep getting the error:
Uncaught TypeError: dispatch(...).then is not a function
Actions.js
export function setComposition(composition) {
return { type: types.SET_COMPOSITION, composition };
}
export function setOutputs(outputs) {
return { type: types.SET_OUTPUTS, outputs };
}
export function setOutputsAndComposition(outputs) {
return function (dispatch, getState) {
return dispatch(setOutputs(outputs)).then(() => // ERROR HERE
dispatch(setComposition(getState().Data.OutputObj))
);
}
}
EDIT: Ideally I would love to just create a function that just does this:
export function setOutputsAndComposition(outputs) {
return function (dispatch, getState) {
dispatch(setOutputs(outputs)).then(() =>
dispatch(setComposition(getState().Data.OutputObj))
);
}
}
But somewhere I'm obviously not doing the syntax correctly
Where does this new dispatch argument come from? The short answer is that the redux-thunk middleware has access to the store, and can therefore pass in the store's dispatch and getState when invoking the thunk. The middleware itself is responsible for injecting those dependencies into the thunk.
Redux Thunk is a middleware that lets you call action creators that return a function instead of an action object. That function receives the store's dispatch method, which is then used to dispatch regular synchronous actions inside the function's body once the asynchronous operations have been completed.
If you pass a function into dispatch , the thunk middleware sees that it's a function instead of an action object, intercepts it, and calls that function with (dispatch, getState) as its arguments. If it's a normal action object (or anything else), it's forwarded to the next middleware in the chain.
As it turns out, Redux already has an official version of that "async function middleware", called the Redux "Thunk" middleware. The thunk middleware allows us to write functions that get dispatch and getState as arguments.
setOutputs()
is returning a plain action object, and thus is not a thunk that returns a promise. So, chaining dispatch(setOutputs(outputs)).then()
won't work.
If you just want to dispatch another action right after the setOutputs()
dispatch is complete, you only need to put them right after each other:
dispatch(setOutputs(outputs));
dispatch(setComposition(getState().Data.OutputObj));
You can use setOutputs()
as a custom middleware. In this case I'm using it as a Promise
instead:
export function setComposition(composition) {
return { type: types.SET_COMPOSITION, composition };
}
export function setOutputs(outputs, dispatch) {
return new Promise((resolve, reject) => {
dispatch({type: types.SET_OUTPUTS, outputs});
resolve();
});
}
export function setOutputsAndComposition(outputs) {
return function (dispatch, getState) {
return setOutputs(outputs, dispatch).then(() => // NO ERROR HERE ANYMORE ^_^
dispatch(setComposition(getState().Data.OutputObj))
);
}
}
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