React file upload returns undefined

Viewed 1025

So I am trying to send an image to my node.js api, but logging the image hook returns undefined. I've tried multiple ways, but each time I get the same undefined messege, I've tried useState([]), useState("") and even the example shown below. Please help end my misery

import Cookies from "universal-cookie";
import FormData from "form-data";

export const CreateRecipe = () => {

  const storageUrl = `http://${process.env.REACT_APP_API_URL}/storage/new`;
  const cookies = new Cookies();
  const token = cookies.get("token");

  const [fileData, setFileData] = useState();
  const getFile = (e) => {
    setFileData(e.target.files[0]);
    console.log(fileData);
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    const formData = new FormData();
    formData.append("image", fileData);
    fetch(storageUrl, {
      method: "POST",
      headers: {
        Authorization: "Bearer " + token,
        "Content-Type": "multipart/form-data",
      },
      body: formData,
    })
      .then((res) => res.json())
      .then((data) => {
        if (data.error) {
          alert(data.message);
        } else {
          console.log(data);
        }
      });
  };

  return (
    <div id="create-recipe">
      <form onSubmit={handleSubmit}>
        <input
          type="file"
          name="image"
          accept="image/*"
          //style={{ display: 'none' }}
          onChange={getFile}
        />
        <button type="submit">Post </button>
      </form>
    </div>
  );
};
1 Answers

const [fileData, setFileData] = useState();

Change the useState to an empty array like this

const [fileData, setFileData] = useState([]);

Your code is almost correct, one thing is to be noted when your input type is file so onChange Method will run only once, when you choose all the files. You can check it like this.

const getFile = (e) => {
 console.log("no of files ",e.target.files.length);
  };

You will see " this no. of files " only one time in console after you have selected all the images.

You need to set FileData for each image. One way to do this is ..

const getFile = (e) => {
 const len = e.event.files.length;
 for(let i=0; i<len; i++){
    setFileData(e.target.files[0]);
    console.log(fileData);
 }
};

Now this will work for sure.

Related