1

In my application after the user submits a form, I have access to an array of images and I need to call our backend to save all of their uploaded photos to our cloud server.

Our /upload api endpoint takes one image at a time. How do I create an api call for each image in this array and chain them to happen one after another? I was thinking I could somehow use reduce to do this, but I'm not 100% sure how to go about it.

Here's how I'm making an api call for single image upload:

    const api = "https://appName.herokuapp.com/upload";
    const uri = photos[0];
    const formData = new FormData();

    formData.append('image', {
      uri,
      name: `photo.jpg`,
      type: `image/jpg`,
    });

    const options = {
      method: 'POST',
      body: formData,
      headers: {
        Authorization:`Basic ${base64.encode(BACKEND_AUTHENTICATION_HEADER)}`,
        Accept: 'application/json',
        'Content-Type': 'multipart/form-data',
      },
    };

    fetch(api, options)
      .catch((e) => console.log(e))
      .then((response) => {
        console.log(response);
      })
Shayan Javadi
  • 293
  • 3
  • 20

2 Answers2

3

Using Promise.All, you should be able to fire off multiple API calls and wait for all of them to resolve. The function passed to then() for a Promise.all receives an array containing the results. For eg:

Promise.all([/*Array of promises*/]).then(function(results){
    //Results is an array
}).catch(function(error){
    //Handle errors
}

Here's a jsFiddle: http://jsbin.com/yuqabizado/2/edit?html,js,output

Edit: - Removed comment about compatibility issues with Promise.all. Thanks @zvona for pointing that out.

Vorcan
  • 116
  • 7
  • 2
    Correct answer: each `fetch` really needs to be handled as a promise in an array and executed with `Promise.all`. And as a sitenote: **RN Supports Promise.all natively, so no need to extend with bluebird**. – Samuli Hakoniemi Oct 28 '17 at 08:06
0

If you're using redux you could do something like:

  • Create an array of images to be uploaded
  • Create an action to upload the image which takes in index as a parameter and will recursively call itself for all following indexes
  • When calling your action pass in index 0 and the action can recursively upload all images from that point

Logic behind this:

imagesArray: [ image1, image2, image3 ]; // each image is an object

Calling your action like:

store.dispatch(Actions.recursivelyUploadImages(0, imagesArray));
// If your action is defined outside of your current scope
// you can either bind it or pass in the imagesArray

Then your action would be defined something like:

recursivelyUploadImages(index, array) {
  // construct/define your api/options here
  fetch(api, options)
      .catch((e) => console.log(e))
      .then((response) => {
        console.log(response);
        if (index < array.length - 1) {
          // call recursiveUploadImages(index+1, array);
        }
      })
}

I don't now if this is a good solution, my knowledge of react and redux is very limited and I can only think about this kind of solution with my current experience.

anteAdamovic
  • 1,462
  • 12
  • 23