Reputation: 11030
I'm having a problem with the flow of redux thunk.
In the action creator, I first create an image object and get the image_id
from the database.
I have a var called clients
which is a list of all the client id's that will need the image id. [1,2,3,4,5]
I go through a for loop, fetch the clients using axios.get and I add the new image_id to the list of images from the client field.
Then I put the new changes to the the clients in the field, client_images
.
export function addNewClient(imageData, clients) {
return function(dispatch) {
axios.post(`${API_URL}/media`, fileData, { withCredentials: true, headers: { 'Content-Type': 'multipart/form-data' } })
.then(response => {
var image_id = response.data.id;
//go through each client to get current background list
for (var i = 0; i < clients.length; i++) {
var currRow = clients[i];
console.log("GETTING NEW CLIENT", currRow)
axios.get(`${API_URL}/clients/${currRow}`, { withCredentials: true })
.then(response => {
var currImages = response.data.client_images;
var clientImages = [...currImages, image_id];
console.log("ADDING NEW CLIENT IMAGE IDs", currRow);
axios.put(`${API_URL}/clients/${currRow}`, {client_images:clientImages}, { withCredentials: true })
})
.catch(() => {
console.log("Can't set image list to clients");
});
}
});
}
}
My problem lies here: The entire for loop is done before I can call
axios.put(`${API_URL}/clients/${currRow}`, {client_images:clientImages}, { withCredentials: true })
In my console, this is the output
As you can see, Adding New Client Images is only called AFTER the for loop is DONE. I need the "Adding New Client Images" to be called INSIDE the for loop so that the other axios function can be called instead of it being called 5 times to the client with id of 5.
Is there a way to get the for loop working in redux thunk?
Upvotes: 0
Views: 451
Reputation: 79338
Ah this one is always tricky at first. When using promises with arrays, use array.map
instead of a for loop. So try changing this:
for (var i = 0; i < clients.length; i++) {
var currRow = clients[i];
axios.get(`${API_URL}/clients/${currRow}`, { withCredentials: true })
// ...
}
To this:
return Promise.all(clients.map(function(currRow){
return axios.get(`${API_URL}/clients/${currRow}`, { withCredentials: true })
// ...
}));
That will make sure all of the promises have their own scope.
So the end result is something like:
export function addNewClient(imageData, clients) {
return function(dispatch) {
axios.post(`${API_URL}/media`, fileData, { withCredentials: true, headers: { 'Content-Type': 'multipart/form-data' } })
.then(response => {
var image_id = response.data.id;
//go through each client to get current background list
return Promise.all(clients.map(function(currRow){
console.log("GETTING NEW CLIENT", currRow)
return axios.get(`${API_URL}/clients/${currRow}`, { withCredentials: true })
.then(response => {
var currImages = response.data.client_images;
var clientImages = [...currImages, image_id];
console.log("ADDING NEW CLIENT IMAGE IDs", currRow);
return axios.put(`${API_URL}/clients/${currRow}`, {client_images:clientImages}, { withCredentials: true })
})
.catch(() => {
console.log("Can't set image list to clients");
});
}));
});
}
}
Upvotes: 3