2

I have this set up where it runs through an array, and saves it into the phone, but it opens the googleUrl before all the media files are downloaded. Shouldn't the Promise.all() take care of this? Isn't it supposed to wait for mapMediaArray to be finished, and .then() the rest of the work?

const mapMediaArray = selectedMedia.map(index => {
  let cleanUrl = `${index.mediaUrl.split('?')[0]}`;
  let extension = cleanUrl.split('.').pop();
  RNFetchBlob.config({
    fileCache: true,
    appendExt: extension,
  })
    .fetch('GET', index.mediaUrl)
    .then(res => {
      CameraRoll.saveToCameraRoll(res.path());
    });
});

Promise.all(mapMediaArray).then(() => {
  Linking.openURL(googleUrl);
});
hellomello
  • 8,219
  • 39
  • 151
  • 297
  • 3
    Because you don't `return` the promises from the `map` callback. Try logging `mapMediaArray` - it's not an array of promises – Bergi Jan 19 '20 at 20:19
  • 1
    @Bergi just got an array of `undefined`. ie: `[undefined, undefined, undefined]` suggestions? – hellomello Jan 19 '20 at 20:21
  • 1
    What I said - add the missing `return` keyword in your callback function – Bergi Jan 19 '20 at 20:26
  • 1
    @Bergi Ah! okay thanks I did it at `return RNFetchBlob` seems to get a promise now! thank you – hellomello Jan 19 '20 at 20:32
  • 2
    Btw, depending on whether `CameraRoll.saveToCameraRoll(…)` is asynchronous and returns a promise, you'll need another `return` there as well – Bergi Jan 19 '20 at 20:45
  • @Bergi thank you so much! saved the issue I was just having right now haha. Much appreciated! If you want to create an answer? I can accept? :) – hellomello Jan 19 '20 at 20:47

1 Answers1

0

It is true that you call a promise inside your method but your method is not a promise. It a synchronous method so as soon as all synchronous codes gets called promise.all() is called. Your method must be something like this to be identified as a valid promise.

const mapMediaArray = selectedMedia.map(index => {
  return new Promise((resolve)=>{
     let cleanUrl = `${index.mediaUrl.split('?')[0]}`;
     let extension = cleanUrl.split('.').pop();
     RNFetchBlob.config({
       fileCache: true,
       appendExt: extension
     })
     .fetch('GET', index.mediaUrl)
     .then(res => {
       CameraRoll.saveToCameraRoll(res.path());
       resolve()
     })
  })
}

Like above code, you have to return a promise and then call resolve in order to make Promise.all work correctly.

Mohammad f
  • 961
  • 10
  • 11
  • 2
    Avoid the [`Promise` constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)! – Bergi Jan 19 '20 at 22:19