I'm trying to create a "Create Post" form where the user can input text, as well as input images.
uploadImages() {
const files = document.querySelector('#imagesInput').files;
files.forEach(image => {
console.log("uploading", image.name)
const name = (+new Date()) + '-' + image.name;
const task = fb.storage.child(name).put(image, {contentType: image.type});
task.then(snapshot => {
snapshot.ref.getDownloadURL().then(url => {
console.log(url);
})
})
});
}
The image upload process needs to happen first, and I need to return all the URLs (as an array) before the post is created in the database.
imageURLs = this.uploadImages(); // <-- Wait for this to complete and return the image URIs
this.createPost("Hello, world!", imageURLs) // <-- then do this
Since you call the asynchronous getDownloadURL()
method a variable number of times (i.e. unknown at the time of coding), you need to use Promise.all()
as follows:
uploadImages() {
const files = document.querySelector('#imagesInput').files;
const promises = [];
files.forEach(image => {
console.log("uploading", image.name)
const name = (+new Date()) + '-' + image.name;
const task = fb.storage.child(name).put(image, { contentType: image.type });
promises.push(task);
});
return Promise.all(promises)
.then(snapshotsArray => {
// snapshotsArray is an array with a variable number of elements
// You again need to use Promise.all
const promises = [];
snapshotsArray.forEach(snapshot => {
promises.push(snapshot.ref.getDownloadURL());
})
return Promise.all(promises);
});
}
The uploadImages()
function is asynchronous and returns a Promise (since Promise.all()
and then()
return Promises): you therefore need to call it by using then()
, as follows:
this.uploadImages()
.then(imageURLs => {
this.createPost("Hello, world!", imageURLs)
})