Home > Mobile >  Async await is not working as expected to work
Async await is not working as expected to work

Time:04-14

I'm trying to set images after uploading them to cloud, but seems like i'm missing something . The output is not as desired .

I expect the output to be having all images. But it is just 0 instead.

 useEffect(() => {
    console.log("============ From UseEffect ==========")
    console.log("Images now Contain : ", images);
  }, [images]);

const uploadFilesToCloud = async () => {
    const data = new FormData();
    for (let i = 0; i < imageUrls.length; i  ) {
      const finalImage = await getBase64FromUrl(imageUrls[i]);
      data.append("file", finalImage);
      data.append("upload_preset", "myPreset");
      const res = await fetch(
        "https://api.cloudinary.com/v1_1/dpurb6xes/image/upload",
        {
          method: "Post",
          body: data,
        }
      );
      const response = await res.json();
      setImages((old) => [...old, response.secure_url]);
    }
  };

const onClick = async (e) => {
await uploadFilesToCloud();
const myForm = {
  name: name,
  imageUrls: images,
};
  console.log("form data is ", myForm);
}

Suprisingly the output is :

enter image description here

My actual question is now .

  1. Though the images has one element before setting myForm.imgUrls = images. Even then myForm.imageUrls is having no element. How ?
  2. And what i want is , after both the received images are set only then the form should be initialized with images.

Can you please say how to do just that.

CodePudding user response:

I don't think there's actually a need for state here. Map the imageUrls array to an array of fetch Promises and return Promise.all from upload. The onClick handler can await the array of Promises to resolve and use the array of resolved image URLs.

Example:

const App = () => {
  const upload = () => {
    const imgURLs = imageUrls.map(data => {
      return fetch(
        "https://api.cloudinary.com/v1_1/dpurb6xes/image/upload",
        {
          method: "Post",
          body: data,
        }
      ).then(response => response.json())
      .then(response => response.secure_url);
    });

    return Promise.all(imgURLs);
  };

  const onClick = async () => {
    const imageURLs = await upload();
    const myForm = {
      formImages: imageURLs,
    };
    console.log("Form details", myForm);
  };

  return (
    <>
      <div className="container">
        <button
          type="button"
          onClick={onClick}
        >
          Click me
        </button>
      </div>
    </>
  );
};

If you needed to store the image URLs in state the place to do that is in the onClick handler once everything resolves.

Example:

const onClick = async () => {
  const imageURLs = await upload();
  const myForm = {
    formImages: imageURLs,
  };
  console.log("Form details", myForm);
  setimages(imageURLs);
};
  • Related