React-Native Expo app async downloads

Viewed 3625

So I am using create-react-native-app to build a project. As you probably know, this uses Expo as a framework when you are developing app.

I am using Expo's FileSystem.downloadAsync() to download files I need. I need multiple files to download, so I run this command inside .map(), something like this:

this.state.files.map(file => {
    FileSystem.downloadAsync(file.url, FileSystem.documentDirectory + file.name)
    .then(({ uri }) => console.log('Saved this file at: ' + uri))
    .catch(console.log('Error when downloading file.'))
})

Now with .then() I know when each file has downloaded, but how do I know when all files has finished downloading?

If I put that in a function and call it, it doesn't wait for it to finish, it just continues to next piece of code.

Could I somehow make that this function returns a new Promise? I think that's a proper way to do it, but I am not sure how do I make it? Where do I put resolve and reject?

1 Answers

Looks like you need Promise.all()! It will except an array of promises and then return a new promise that will resolve after each promise in the array has returned a result.

If you look here in the expo docs on preloading and caching assets you will see a good example of this.

async _loadAssetsAsync() {
  const imageAssets = cacheImages([
      'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png',
      require('./assets/images/circle.jpg'),
  ]);

  const fontAssets = cacheFonts([FontAwesome.font]);

  // Notice how they create an array of promises and then spread them in here...
  await Promise.all([...imageAssets, ...fontAssets]);
}

In your case something like this would work

const assets = this.state.files.map(file =>
    FileSystem.downloadAsync(file.url, FileSystem.documentDirectory + file.name)
)
/// Here is where you put the try.
try {
  await Promise.all(assets);
} catch (error) {
  /// Here is where you would handle an asset loading error.
  console.error(error)
}
console.log("All done loading assets! :)");
Related