0

This function to post images array to firebase storage and get urls to post them on firebase database.

uploadImages(images, callBack) {
    this.uploadedImages = [];
    for (let index = 0; index < images.length; index++) {
      const imagesURI = storage()
        .ref("images/")
        .child(this.uid())
        .child(index + "");
      imagesURI.putString(images, "data_url").then(() => {
        imagesURI.getDownloadURL().then(url => {
          console.log(url);
          this.uploadedImages.push(url);
          console.log(this.uploadedImages);
        });
      });
    }
    callBack(this.uploadedImages);
  }

How can I use Promise.all in this case?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Welcome to StackOverflow. Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. Read [How To Ask](https://stackoverflow.com/help/how-to-ask) to know how you can ask a good question. :-) – Sanju Oct 09 '18 at 12:13

2 Answers2

1

Both putString and getDownloadURL return a promise, so you can just bubble them up, and add them to an array for Promise.all.

uploadImages(images, callBack) {
    let promises = [];
    for (let index = 0; index < images.length; index++) {
      const imagesURI = storage()
        .ref("images/")
        .child(this.uid())
        .child(index + "");
      let promise = imagesURI.putString(images, "data_url").then(() => {
          return imagesURI.getDownloadURL();
        })
      promises.push(promise);
    }
    Promise.all(promises).then(function(urls)
      this.uploadedImages = urls;
      callBack(this.uploadedImages);
    });
}

Note that I only focused on the use of promises to capture when the uploads complete. There may be other mistakes in the code.

As Bergi commented, you can also replace the callback with returning a promise:

uploadImages(images, callBack) {
    let promises = [];
    for (let index = 0; index < images.length; index++) {
      const imagesURI = storage()
        .ref("images/")
        .child(this.uid())
        .child(index + "");
      let promise = imagesURI.putString(images, "data_url").then(() => {
          return imagesURI.getDownloadURL();
        })
      promises.push(promise);
    }
    return Promise.all(promises)
}

With this you can call it with:

uploadImages(imageArray).then(function(downloadUrls) {
  console.log(downloadUrls);
})
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • You'll probably want to drop the `callback` parameter and instead return the promise - so that rejections can be handled. Also [drop the pointless `.then(url => { return url })`](https://stackoverflow.com/q/41089122/1048572) – Bergi Oct 09 '18 at 18:59
  • Yeah, I was indeed thinking about it returning a promise, but decided against it since the call site was missing from the question. But returning `Promise.all()` would definitely be cleaner. I added an example of that. Also: good catch about the self-returning URL, I didn't even read that part of the code (just made it syntactically correct). :-) – Frank van Puffelen Oct 09 '18 at 20:10
  • very thanks for you @FrankvanPuffelen the issue was solved after your answer – Mahmoud Tamer Oct 10 '18 at 11:44
0

Your uploadImages function calls the callback function with the array of promises.

You can simply pass a callback function to "uploadImages" and use the returned array or promises with Promise.all.

uploadImages(images, promises => {
  Promise
    .all(promises)
    .then(results => { 
      //do something with 
    })
    .catch(error => {
      // handle error
    })
})
Faheem
  • 1,105
  • 11
  • 28