2

Im trying to upload an image to cloudinary from react, i am unable to make a post request using axios . This is the code :

 const onSubmit = async (data) => {
    const { files } = document.querySelector('input[type="file"]');
    console.log(data);
    if (data.files !== undefined || data.files !== null || data.files !== "") {
      setLoading(true);
      const formData = new FormData();
      formData.append("file", files[0]);
      formData.append("upload_preset", cloudinary_preset);
      const options = {
        headers: { "Content-Type": "multipart/form-data" },
        data: formData,
      };
      const res = await axios.post(
        `https://api.cloudinary.com/v1_1/${cloudinary_id}/image/upload`,
        options
      );
      const img = await res.json();
      const imgUrl = img.secure_url;
      data.thumbnail = imgUrl;
      console.log(data.thumbnail);
      console.log(res);
      setLoading(false);
    } else {
      data.thumbnail = "";
    }
   };

the response that i got on my browser console : enter image description here

But when i use fetch , i am successfully uploaded my images . Here is the code :

 const onSubmit = async (data) => {
    const { files } = document.querySelector('input[type="file"]');
    console.log(data);
    if (data.files !== undefined || data.files !== null || data.files !== "") {
      setLoading(true);
      const formData = new FormData();
      formData.append("file", files[0]);
      formData.append("upload_preset", cloudinary_preset);
      const options = {
        method: "POST",
        body: formData,
      };
      const res = await fetch(
        `https://api.cloudinary.com/v1_1/${cloudinary_id}/image/upload`,
        options
      );
      const img = await res.json();
      const imgUrl = img.secure_url;
      data.thumbnail = imgUrl;
      console.log(data.thumbnail);
      console.log(res);
      setLoading(false);
    } else {
      data.thumbnail = "";
    }
    };

the responses :

enter image description here

My guess that i conclude from the web console is on the headers part, when i use axios even tho i already change the headers to content-type:multipart/form-data , it still being sent as application/json. But then again im still learning to read the console log , if someone know what is really happening please share your opinion!

2 Answers 2

1

You are getting application/json type because you are passing JS object options to data part in your Axios post call.

Setting headers should be done in 3rd argument of .post method:

Here is modified code where options variable is removed:

const onSubmit = async (data) => {
  const { files } = document.querySelector('input[type="file"]');
  console.log(data);
  if (data.files !== undefined || data.files !== null || data.files !== '') {
    setLoading(true);

    const formData = new FormData();
    formData.append('file', files[0]);
    formData.append('upload_preset', cloudinary_preset);
    const res = await axios.post(
      `https://api.cloudinary.com/v1_1/${cloudinary_id}/image/upload`, 
      formData, 
      {
        headers: { 'Content-Type': 'multipart/form-data' }
      }
    );
    const img = await res.json();
    const imgUrl = img.secure_url;
    data.thumbnail = imgUrl;
    console.log(data.thumbnail);
    console.log(res);
    setLoading(false);
  } else {
    data.thumbnail = '';
  }
};

Axios docs https://axios-http.com/docs/api_intro:

axios.post(url[, data[, config]])

NOTE

I think that when you add FormData type of data to body, axios will se Content-Type to be multiplart/form-data implicitly.

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

2 Comments

I figured it out , my logic was the problem! turns out that when using axios it returns a promise , hence i need to use then & catch. And you are right, axios automatically see the content as multipart/form-data, because when i remove the headers config im still be able to make post request! code shared below.
Yes, it does return Promise, but you dont need to use then/catch. You can also use await as you did. await is made to handle Promise :) so try it again with await and see if FormData was your only problem.
0

Turns out that axios return a promise , hence i need to use then&catch to make it works, here is my working solution :

const onSubmit = async (data, e) => {
    const { files } = document.querySelector('input[type="file"]');
    console.log(data);
    if (data.files !== undefined || data.files !== null || data.files !== "") {
      setLoading(true);
      const formData = new FormData();
      formData.append("file", files[0]);
      formData.append("upload_preset", cloudinary_preset);
      await axios
        .post(
          `https://api.cloudinary.com/v1_1/${cloudinary_id}/image/upload`,
          formData
        )
        .then((result) => {
          const img = result.data;
          const imgUrl = img.secure_url;
          data.thumbnail = imgUrl;
          setLoading(false);
        })
        .catch((err) => console.log(err));
    } else {
      data.thumbnail = "";
    }

    try {
      setLoading(true);
      await authAxios
        .post("/api/project/", data)
        .then((res) => {
          console.log(res.data);
        })
        .catch((e) => {
          console.log(e);
        });
      setLoading(false);
      reset();
    } catch (err) {
      console.log(err);
    }
  };

After the images is uploaded to cloudinary , i fetch it to the data which then is gonna be sent to my mongodb along with the text form data.

Comments

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.