Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to delay a function until after a forEach statement completes?

I am currently working on a messaging application using React. At the moment, I am struggling with determining a method of delaying the main function that posts a message to the chat.

The main issue is working with the Cloudinary API, for picture message submission, I need the urls that are spit out from the POST request.Thus, I also need the postMessage method to be delayed until after my photos have been uploaded to Cloudinary Database, and the ‘temp’ array has collected the new generated image urls. My issue begins and most likely ends with the fact that I cannot determine the proper way to delay postMessage until my forEach statement completes.

Here is the code for my handleSubmit Method:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

const handleSubmit = async (event) => {
    event.preventDefault();

    const formElements = event.currentTarget.elements;
    const formData = new FormData();
    let temp = [];

    if (imagesSelected.length > 0) {
      imagesSelected.forEach((image) => {
        formData.append('file', image);
        formData.append('upload_preset', 'sendpics');
        
        instance.post('https://api.cloudinary.com/v1_1/dg7d5il8f/image/upload', formData )
        .then((res) => {
          temp.push(res.data.url);
        })
        .catch((err) => {
          console.log(err);
        });
      });

      const reqBody = {
        text: formElements.text.value,
        recipientId: otherUser.id,
        conversationId,
        sender: conversationId ? null : user,
        attachments: temp,
      };
          
      postMessage(reqBody);
    } else {
      const reqBody = {
        text: formElements.text.value,
        recipientId: otherUser.id,
        conversationId,
        sender: conversationId ? null : user,
        attachments: [],
      };
          
      postMessage(reqBody);
    }

    setText('');
    setImagesSelected(() => []);
  };

The issue remains in the first if statement, as once the forEach statement triggers, postMessage triggers right after, before temp even has a chance to be populated with the new url values. Apologies if the whole question itself is convoluted by any means. Please comment if I need to clarify anything about my question. Thanks for any help/suggestions!

>Solution :

I think you’ll need to await them with for-of loop using-async-await-with-a-foreach-loop
An example with your case:

for (const image of imagesSelected) {
  //...
  try {
    const resp = await instance.post(
      "https://api.cloudinary.com/v1_1/dg7d5il8f/image/upload",
      formData
    );
    temp.push(resp.data.url);
  } catch (error) {
    console.log(error);
  }
}

Another approach is replacing forEach with map and adding Promise.all As E. Shcherbo mentioned in comments

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading