Reputation: 29
So I have the following function that takes all the picture uris in state and uploads them to firebase storage and then replaces the uris in state with the firebase download urls that were generated when the pictures were uploaded:
uploadImages = async (userID) => {
//loop through every image
for (var index = 0; index < this.state.images.length; index++) {
//convert image uri to blob
const response = await fetch(this.state.images[index]);
const blob = await response.blob();
//upload image to firebase
let refer = firebase.storage.ref().child('images/' + userID + '/image' + (index + 1));
refer.put(blob)
.then((snapshot) => {
snapshot.ref.getDownloadURL().then((downloadURL) => {
//update image url in state
let images = this.state.images
images[index] = downloadURL
this.setState({images: images});
});
})
.catch((error) => {
alert(error);
});
}
}
What I want to do is call another function, updateData, which will upload all the information in state to a firebase database. The thing is, I want to do this after all pictures have been uploaded and all download urls are in state. I tried simply calling the function after the for loop, but this doesn't seem to work as .put() is asynchronous and therefore the for loop finishes before the pictures are uploaded and before the download urls are in state. Then I tried this:
.then((snapshot) => {
snapshot.ref.getDownloadURL().then((downloadURL) => {
//update image url in state
let images = this.state.images
images[index] = downloadURL
this.setState({images: images});
//call updateData when the last picture has been uploaded
if (index === (this.state.images.length - 1)){
this.updateData(userID);
}
});
})
But this also didn't work because by the time the callback function in .then is called, the loop has already ran its course and index is already +1 than this.state.images.length. So is there anyway to do this? I want updateData to be called only once after the last image has been uploaded.
Upvotes: 0
Views: 728
Reputation: 317760
If you have multiple promises that you need to wait on, collect them all into an array and use Promise.all()
, passing it that array, which returns a new promise that resolves only after all the promises in the array are resolved.
Upvotes: 2