I have a problem with updating my state from nested axios call inside forEach loop:
constructor(props) {
super(props);
this.state = {
isLoaded: false,
items: []
};
//Binding fetch function to component's this
this.fetchFiles = this.fetchFiles.bind(this);
}
componentDidMount() {
this.fetchFiles();
}
fetchFiles() {
axios.get('/list')
.then((response) => {
var items = response.data.entries;
items.forEach((item, index) => {
axios.get('/download'+ item.path_lower)
.then((response) => {
item.link = response.data;
})
.catch(error => {
console.log(error);
})
});
this.setState(prevState => ({
isLoaded: true,
items: items
}));
console.log(this.state.items);
})
.catch((error) => {
console.log(error);
})
}
The idea is to get all items from Dropbox using it's API (JavaScript SDK) and then for each item I also need to call different API endpoint to get a temporary download link and assign it as a new property. Only after all items will get their links attached I want to setState and render the component. Could somebody please help with this, I spend already multiple hours fighting with promises :S
You could use Promise.all
to wait for multiple promises. Also keep in mind that setState
is async and you wont see immediate changes. You need to pass a callback.
fetchFiles() {
axios.get('/list')
.then((response) => {
var items = response.data.entries;
// wait for all nested calls to finish
return Promise.all(items.map((item, index) => {
return axios.get('/download'+ item.path_lower)
.then((response) => {
item.link = response.data;
return item
});
}));
})
.then(items => this.setState(prevState => ({
isLoaded: true,
items: items
}), () => console.log(this.state.items)))
.catch((error) => {
console.log(error);
})
}