3

I have here a problem with multiple images. My problem is that I want to upload multiples image through an API. The API can't handle it through one request. That's why I wanted to upload images one by one and call the API one by one. How do i do it?

export const saveImages =
  ({ images = [], oldImages, isNew }) =>
  async (dispatch) => {
    try {
      dispatch({
        type: constants.REQUEST,
      });

      let responses;

      if (images?.length) {
        let formData = new FormData();

        const requests = images.map(({ imageFileName, imageFile }) => {
          formData.append(imageFileName, imageFile);
          formData.append("isNewProduct", isNew);
          
          return axios.post(
            `${URL}/saveImages`,
            formData
          );
        });

        responses = await Promise.all(requests);
      }

      dispatch({
        type: constants.SUCCESS,
        payload: [...(oldImages || []), ...response?.data],
      });
    } catch (error) {
      dispatch({
        type: constants.FAILURE,
      });
    }
  };
8
  • It looks like it's not about React but axios library Commented Dec 15, 2021 at 5:15
  • Are you asking how to iterate the images array and make individual network requests? What is the point of having a "/bulk-upload-image" endpoint if you can't bulk upload to it? Do you have a different endpoint to use for single individual uploads? What have you tried already? Commented Dec 15, 2021 at 6:21
  • @DrewReese. Yes I want to iterate images and make individual api request. This is what I have tried so far. My problem is I want to make multiple request but have to wait for others to finish and dispatch success as one. Commented Dec 15, 2021 at 6:28
  • Does response = await axios.post(`${URL}/bulk-upload-image`, formData); not process them all at once and give you success? If you really need to split them up into individual requests then map the images to an array of Promises (axios.post) and await Promise.all(....) them. When all mapped promises resolve then Promise.all resolves. Commented Dec 15, 2021 at 6:32
  • @DrewReese. I don't want to process them in one request. I'm experimenting on multiple request if possible. Can you help me answer this question by mapping them the images and using Promise.all? Thank you Drew Commented Dec 15, 2021 at 6:35

1 Answer 1

2

If you really need to split them up into individual requests then map the images to an array of Promises (axios.post) and await Promise.all(....) them. When all mapped promises resolve then Promise.all resolves.

export const uploadMultipleImages = ({ images }) => async (dispatch) => {
  try {
    dispatch({ type: constants.REQUEST });

    // Map images to array of axios.post Promises
    const requests = images.map(({ imageFileName, imageFile })=> {
      const formData = new FormData();
      formData.append(imageFileName, imageFile);
      return axios.post(`${URL}/upload-image`, formData);
    });

    // await all promises to resolve, responses is an array of all
    // resolved Promise values, i.e. whatever the POST requests
    // return
    const responses = await Promise.all(requests);

    dispatch({
      type: constants.SUCCESS,
      payload: responses,
    });
  } catch (error) {
    dispatch({ type: constants.FAILURE });
  }
};

If I recall correctly on previous questions sometimes the images would have missing properties, so if this is still the case then you may want to use a .filter function before mapping to POST requests.

Sign up to request clarification or add additional context in comments.

6 Comments

@Joseph I think it should probably be payload: [...(oldImages || []), ...responses], but otherwise, yeah, seems alright. May want to just give responses an initial value, i.e. let responses = [], this way if no POST requests are made then you only spread an empty array.
@Joseph Oh, you are using only a single formData object and keep appending into it. Notice in my answer a new formData is created for each request. It's inside the map callback.
@Joseph The await is on the Promise.all since it returns a Promise.
@Joseph In the request config there appears to be an onUploadProgress property. I've never done any sort of progress processing so this is about as far as I can get you currently.
Hi again Drew. regarding this one. can we do the request one by one. Like if we finish the first one, it will proceed to the next one and so on. Not doing request simultaneously?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.