New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add possiblity to dispatch other actions on success, fail #21
Comments
It's not possible with redux-api-middleware. That's a great weakness. |
👍 |
Yep. This is a MUST feature. Otherwise this middleware is way too limited. For example, if the request is successful, I may want to redirect to user to another page using I'd really like to see this feature. The works so far is very good. This would really make it an AWESOME middleware. I get tired of having to write a middleware for API calls for every project. |
Maybe we can do that by adding a onSuccess/onFailure to the API call parameters. Thoughts? |
@Sparragus its actually pretty easy to do right now without modifying the library, although I think this would be a nice feature to add anyway. You can add export function doStuff() {
return dispatch => {
dispatch({
[CALL_API]: {
...
types: [
Constants.SOMETHING_FETCHED,
{
type: Constants.SOMETHING_FETCHED_SUCCEEDED,
payload: (action, state, res) => {
return res.json().then(json => {
dispatch(myAction());
return json;
});
},
},
Constants.SOMETHING_FETCHED_FAILED,
],
... |
I thought on dispatching an action inside the payload function but I doesn't feel it's right. That function converts the response to another format and the action I'm already working on onSucceed and onFailure and using it on my project. Hopefully I can send that pull request before v1.0.0 gets out. |
Yeah in my case I dont have any requirement that I need the SUCC action to hit the store before the onSucc dispatched action hits it. I just want to fire something on a 200 response code. Looking forward to the PR! |
+1 |
I'm working on this and already using it. So far what I have are two new properties you may (but don't need to) add to the I do have one bug with the EDIT: The
The code I have so far is this:
My question to you: how is it looking so far? Thoughts? |
Just use thunk and promises, way cleaner than callbacks. |
@masad-frost Can you post an example? |
Hi, I can also confirm that dispatching "thunks" is working without any problem (v1.0.0-beta3), @Sparragus here is an example: export function patchAsyncExampleThunkChainedActionCreator(values) {
return async(dispatch, getState) => {
const actionResponse = await dispatch({
[CALL_API]: {
endpoint: "...",
method: "PATCH",
body: JSON.stringify(values),
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
},
types: [PATCH, PATCH_SUCCESS, PATCH_FAILED]
}
});
if (actionResponse.error) {
// the last dispatched action has errored, break out of the promise chain.
throw new Error("Promise flow received action error", actionResponse);
}
// you can EITHER return the above resolved promise (actionResponse) here...
return actionResponse;
// OR resolve another asyncAction here directly and pass the previous received payload value as argument...
return await yourOtherAsyncAction(actionResponse.payload.foo);
};
} |
Oh wow, @majodev. THIS CHANGES EVERYTHING. :D I didn't know that |
In the docs for redux-thunk there's a section on composition that explains this further: // In fact I can write action creators that dispatch
// actions and async actions from other action creators,
// and I can build my control flow with Promises.
function makeSandwichesForEverybody() {
return function (dispatch, getState) {
if (!getState().sandwiches.isShopOpen) {
// You don’t have to return Promises, but it’s a handy convention
// so the caller can always call .then() on async dispatch result.
return Promise.resolve();
}
// We can dispatch both plain object actions and other thunks,
// which lets us compose the asynchronous actions in a single flow.
return dispatch(
makeASandwichWithSecretSauce('My Grandma')
).then(() =>
Promise.all([
dispatch(makeASandwichWithSecretSauce('Me')),
dispatch(makeASandwichWithSecretSauce('My wife'))
])
).then(() =>
dispatch(makeASandwichWithSecretSauce('Our kids'))
).then(() =>
dispatch(getState().myMoney > 42 ?
withdrawMoney(42) :
apologize('Me', 'The Sandwich Shop')
)
);
};
}
// This is very useful for server side rendering, because I can wait
// until data is available, then synchronously render the app.
store.dispatch(
makeSandwichesForEverybody()
).then(() =>
response.send(React.renderToString(<MyApp store={store} />))
); |
@majodev I tried to use your code, but the following statement return undefined
What am I missing here? |
@quangthe You need ES2017 or greater which supports
It can be done with plain promises too:
|
@RanzQ Thanks for your answer, I would go with plain promise instead because of ES6 in my project. |
Whats the status of this one? Does Anyone want to help with some docs on this subject? |
I am still getting an I am using es2017, regardless, I get this from doing both anyone have any insight? |
Not sure if this will be helpful, but using @majodev's example I've written a custom middleware that essentially wraps RSAA actions and handles onSuccess & onFailure callbacks: export const apiMiddlewareWrapper = ({dispatch}) => next => (action) => {
if(!isRSAA(action)) {
return next(action);
}
const {onSuccess, onFailure, ...rsaaAction} = action;
if(!onSuccess && !onFailure) {
return next(rsaaAction);
}
return (async() => {
const response = await next(rsaaAction);
if(response.error && onFailure) {
dispatch(onFailure);
} else if(onSuccess) {
dispatch(onSuccess);
}
return response;
})();
}; |
@zandersays I've seen reports of this being caused by middleware order #179 (comment) Does that help at all? I'm going to close this issue out since there does seem to be an accepted answer and I've documented it in the readme. Feel free to keep this thread going or to open new issues to continue. |
@nason I figured out what the issue was. On top off middleware order, any middleware that calls This was hard to catch, because Regardless, I got it figured out, and your direction helped me immensely. Thanks much. |
@zandersays That was the solution for me! Thank you for finding the error! |
I think it's a must required feature - to be able to dispatch other actions on success/fail. Perhaps using meta object ? Or new object 'cb' ?!
The text was updated successfully, but these errors were encountered: