Reputation: 354
I have this two functions, writedb is supposed to act only when uploadImages is done. I'm not getting what I'm hoping for. The resolve shows "null" for "this.imageURL" as is predefined but is triggered before the console.log that are inside the loop which show the correct wanted information.
uploadImages() {
return new Promise(async (resolve, reject) => {
let newImageURL = []
for (const path of this.images){
fs.readFile(path,
async (err, data) => {
const ref = st.ref(`images/${this.id}/${path.split('/').pop()}`);
await ref.put(data);
let url = await ref.getDownloadURL();
newImageURL.push(url);
this.imageURL = newImageURL;
console.log(this.imageURL);
})
}
resolve(console.log(this.name),
console.log(this.imageURL),
console.log('Done upload images'))
})
}
writedb(){
(() => {
let obj = {};
this.uploadImages().then(
console.log('writedb in action...'),
db.collection("products").doc(this.id).set(Object.assign(obj, this))
)
})();
}
What am I doing wrong here? How can i get the promise to resolve only if the for loop is done??
Upvotes: 1
Views: 365
Reputation: 354
With CertainPerformance help I've corrected my code as follows
Thank you! After some though I finally was able to implement it and achieve the expected result.
uploadImages (){
return Promise.all(this.imagespath.map(
path => fs.promises.readFile(path)
.then(async (data)=>{
const ref = st.ref(`images/${this.id}/${path.split('/').pop()}`);
await ref.put(data);
return ref.getDownloadURL();
})
))
}
writedb(){
this.uploadImages()
.then((res)=>{
this.imageURL = res;
//Firebase no toma custom objects Object.assign(obj, this)
let obj ={}
Object.assign(obj, this);
delete obj.imagespath;
db.collection("products").doc(this.id).set(obj)
}).catch( err=>console.log(err) )
}
Upvotes: 0
Reputation: 370679
Use fs.promises
and Promise.all
to wait for each readFile
to resolve - and avoid the explicit Promise construction antipattern:
uploadImages() {
return Promise.all(this.images.map(
path => fs.promises.readFile(async (data) => {
const ref = st.ref(`images/${this.id}/${path.split('/').pop()}`);
await ref.put(data);
return ref.getDownloadURL();
})
));
}
Then instance.uploadImages()
will return a Promise that resolves to an array of the data you want. uploadImages().then((result) => { /* do stuff with result */ }).catch(handleErrors);
Upvotes: 2