Upload Image Request from React

Viewed 17058

What I am trying to achieve is to send a request from the Client Side (React) to the Server Side (Express) containing the uploaded image file

Here an example of a form I created on the Server which sends the data I should be sending with React instead:

<form method="post" action="post" enctype="multipart/form-data">
  <input type="file" name="image" /><br /><br />
  <button type="submit" name="upload">Upload</button>
</form>

This is the object sent by the submitted form when uploaded an image: link

Here the React Component:

const Component = () => {
  const setImageAction = async (event) => {
    event.preventDefault();

    const data = await fetch("http://localhost:3000/upload/post", {
      method: "post",
      headers: { "Content-Type": "multipart/form-data" },
      body: JSON.stringify({

      }),
    });
    const uploadedImage = await data.json();
    if (uploadedImage) {
      console.log('Successfully uploaded image');
    } else {
      console.log('Error Found');
    }
  };

  return (
    <div className="content">
      <form onSubmit={setImageAction}>
        <input type="file" name="image" />
        <br />
        <br />
        <button type="submit" name="upload">
          Upload
        </button>
      </form>
    </div>
  );
};

As you can see, in the React Component the body request is empty as I haven't figured out how to retrieve that file object..

Thank you in advance for your help!

EDIT

Updated as shown, with the only difference of keeping State as Hook

Here the new React Component Code:

const LandingPage = () => {
  const [picture, setPicture] = useState({});

  const uploadPicture = (e) => {
    setPicture({
      /* contains the preview, if you want to show the picture to the user
           you can access it with this.state.currentPicture
       */
      picturePreview: URL.createObjectURL(e.target.files[0]),
      /* this contains the file we want to send */
      pictureAsFile: e.target.files[0],
    });
  };

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

    const formData = new FormData();
    formData.append("file", picture.pictureAsFile);

    console.log(picture.pictureAsFile);

    for (var key of formData.entries()) {
      console.log(key[0] + ", " + key[1]);
    }

    const data = await fetch("http://localhost:3000/upload/post", {
      method: "post",
      headers: { "Content-Type": "multipart/form-data" },
      body: formData,
    });
    const uploadedImage = await data.json();
    if (uploadedImage) {
      console.log("Successfully uploaded image");
    } else {
      console.log("Error Found");
    }
  };

  return (
    <div className="content landing">
      <form onSubmit={setImageAction}>
        <input type="file" name="image" onChange={uploadPicture} />
        <br />
        <br />
        <button type="submit" name="upload">
          Upload
        </button>
      </form>
    </div>
  );
};

And here what I get from those console.logs: link

I created a snippet in codesandbox if you want to have a look at: https://codesandbox.io/s/heuristic-snyder-d67sn?file=/src/App.js

1 Answers

add this method to capture the onChange event :

add 2 properties to your state : picturePreview and pictureAsFile

uploadPicture = (e) => {
        this.setState({
            /* contains the preview, if you want to show the picture to the user
               you can access it with this.state.currentPicture
           */
            picturePreview : URL.createObjectURL(e.target.files[0]),
            /* this contains the file we want to send */
            pictureAsFile : e.target.files[0]
        })
    };

now, on your onSubmit event :

setImageAction = () => {
        const formData = new FormData();
        formData.append(
            "file",
            this.state.pictureAsFile
        );
        // do your post request

    };

of course don't to add the uploadPicture method to your input:

 <input type="file" name="image" onChange={this.uploadPicture}/>

EDIT

to display your formData :

for (var key of formData.entries()) 
{
    console.log(key[0] + ', ' + key[1])
}
Related