-
-
Notifications
You must be signed in to change notification settings - Fork 15.3k
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
whats the redux idiom for waiting for multiple async calls? #723
Comments
I'm assuming you use Redux Thunk middleware. Declare some action creators: import 'babel-core/polyfill'; // so I can use Promises
import fetch from 'isomorphic-fetch'; // so I can use fetch()
function doSomething() {
return dispatch =>
fetch(
'/api/something'
).then(
response => response.json()
).then(
json => dispatch({ type: DO_SOMETHING, json }),
err => dispatch({ type: SOMETHING_FAILED, err })
);
}
function doSomethingElse() {
return dispatch =>
fetch(
'/api/something'
).then(
response => response.json()
).then(
json => dispatch({ type: DO_SOMETHING_ELSE, json }),
err => dispatch({ type: SOMETHING_ELSE_FAILED, err })
);
} Note how I make it a point to return a store.dispatch(doSomething()).then(() => {
console.log('I did something');
}); When you use Redux Thunk, This lets you use combinators like Promise.all([
store.dispatch(doSomething()),
store.dispatch(doSomethingElse())
]).then(() => {
console.log('I did everything!');
}); However it is preferable to define another action creator that would act as a composition of the previous action creators, and use function doEverything() {
return dispatch => Promise.all([
dispatch(doSomething()),
dispatch(doSomethingElse())
]);
} Now you can just write store.dispatch(doEverything()).then(() => {
console.log('I did everything!');
}); Happy dispatching! |
@gaearon Is there any particular reason that you favor |
No particular reason, I'm just more familiar with it. |
Understood, thanks! |
if you want you can take a look on it https://github.com/Cron-J/redux-async-transitions |
@gaearon quick question - looking at your example above, where you call: store.dispatch(doSomething()).then(() => {
console.log('I did something');
}); — it looks like that "I did something" block would be hit even if |
It is just an example, I don’t mean this a definitive reference, just as a way to look at it. I didn’t give it a minute of real thought. You know how to return promises from action creators, the rest is up to you. Whether to rethrow errors, where to handle them, is all up to you. This is not really a Redux concern so my advise is as good as anyone else’s, and in this case you have much more context on what you want build and the style you prefer than I will ever have. |
Cool, thanks! Figured that was the case, but wanted to make sure there wasn't some magic I was overlooking. |
Since Redux is customizable, Actually, I ran into one issue in real life since I takes redux-loop. It tweaks |
Well, as Dan said above in this thread: it's your app, you are writing your action creators, so you get to decide what they return. |
@markerikson The return value of But, I got a workaround. Instead of chain |
Yes, middleware can tweak things, but my point is that you are setting up the middleware in your own app :) |
Hi @gaearon, quick (hopefully related) question! What are your views on doing something like function fetchDataBWhichDependsOnA() {
return dispatch => {
dispatch(fetchDataA())
.then(() => {
fetch('/api/get/data/B')
.then(dispatch(receiveDataB(response.data)))
})
}
} There are 2 nested async actions in this code snippet, they work but I'm having trouble testing it. I'm able to test |
@timothytong You are not returning the promises. If you return the result from |
@johanneslumpe good catch, thanks mate! Now all that's left is the question of whether this is acceptable or not, dealing with data dependency with an async fetch chain? |
I had the same problem and spent 30 minutes trying to come up with a solution. I'm not done this implementation, but I feel like it's on the right track. https://github.com/Sailias/sync-thunk My idea is that a component can request certain redux states to be populated, if they are not it should refer to a map to call the actions to populate them and chain them with |
I have a question on this. Sorry if it is so basic. In this scenario, there will be two dispatches. That means, two times the component will be rendered. But, what if component wants both data to show something meaningful? So, in that scenario, I would like the component to render only once and that is when all the async actions are completed. I got names of few middlewares which seem to be handling this issue like redux-batched-subscribe and redux-batched-actions. But, a little confused on the best approach. If this is a valid scenario, what would be the suggested approach to handle this? |
@jintoppy if your ask is to avoid multiple call to render a component then the |
@jintoppy why do you need any middlwares to handle your situation?
You can just put all your request into the one action creator and fire dispatching of action only once all of them are resolved. In that case you have reducer called and thus state changed only once, so render() likely will be fired only once as well. |
@apranovich: I see one problem with this approach. Now, I need to combine multiple fetch in a single action. So, if I have, let's say 10 async calls, I have to put all those in a single action. Also, what if I want to trigger one out of these 10 async calls later? In this approach, basically, all your async logic will lie in a single action. |
Thank you all for the helpful information. Quick question, how can the same be achieved but instead when one fetch returns data that is required by the next fetch method. For example, there is a free weather API endpoint where I input the geolocation to get an id (first |
Hi @gaearon, I would like to get your review on this question of mine. I have to make nested async calls to two APIs. The response from the second API is dependent on the response of the first one.
I tried something like above, but this doesn't work.And in my project, I have to use response from both the APIs independently. Thanks. |
@c0b41 , please check the updated question. |
hey @c0b41 , this is giving syntax errors in the second axios call. |
@aayushis12 , @c0b41 : this is a bug tracker, not a help forum. You should try asking this question on Stack Overflow or Reactiflux. There will be more people who will see the question and be able to help. |
For those experiencing that
is printed before all async calls are resolved, check whether you're returning a statement or an expression from your async action creators. For example, if
"I did everything" will print before |
@gaearon one question, based on #723 (comment) how would you handle it if you need to dispatch an action that waits for two actions to have been dispatched AND the state to have changed because of those actions? I'm having a case in which the actions are dispatched but the action inside the |
@enmanuelduran : Dan isn't an active maintainer any more - please don't ping him. It's hard to answer your question without seeing code, but our issues really aren't intended to be a discussion forum. It would be better if you post your question on Stack Overflow - you're likely to get a better answer there, faster. |
@markerikson oh, sorry, it was not my intention, created a question in stackoverflow if someone is interested: https://stackoverflow.com/questions/51846612/dispatch-an-action-after-other-specific-actions-were-dispatched-and-state-change thanks a lot guys. |
When i initiate react component, I need to make 2 different async http calls and wait for their results.
These 2 calls will ideally put their data in 2 different reducers.
I understand the pattern for making a single async call.
However, I dont see any good samples for making multiple async calls, having them execute in parallel and wait for both their results to arrive.
What is the redux way of doing this?
The text was updated successfully, but these errors were encountered: