9

I am trying to send a form to my Express.js back-end using react form. It is sending only the texts but not the file. Do I need to build up a FormData when sending files through the form? Here is my form on App.js

    class App extends Component {
     constructor(props) {
      super(props);
       this.state={
        inputTopValue:'',
        inputBottomValue:'',
        inputImageValue: '',
            }
    this.handleTopChange = this.handleTopChange.bind(this);
    this.handleBottomChange = this.handleBottomChange.bind(this);
    this.handleImageChange = this.handleImageChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
             }

    handleTopChange(event) {
       this.setState({inputTopValue: event.target.value});
               }

   handleBottomChange(event) {
    this.setState({inputBottomValue: event.target.value});
             }

   handleImageChange(event) {
    this.setState({inputImageValue: event.target.value
              }

   handleSubmit(event) {
    event.preventDefault();
    fetch('api/learning', {
        method: 'POST',
        headers: {
          'Content-Type': 'multipart/form-data',
          'Accept': 'application/json'
        },
         body: JSON.stringify({
             topstuff: event.target.topstuff.value,
             bottomstuff: event.target.bottomstuff.value,
             pic1: event.target.myimage.value

         })
    })
  }

   render() {
       return (
         <div className="App">
           <form onSubmit={this.handleSubmit} id="myform" encType="multipart/form-data">
              <input type="text" name="topstuff" placeholder="title" onChange={this.handleTopChange} value={this.state.inputTopValue} /> <br/>
              <input type="text" name="bottomstuff" placeholder="body" onChange={this.handleBottomChange} value={this.state.inputBottomValue} /><br/>
              <input type="file" name="myimage" onChange={this.handleImageChange} value={this.state.inputImageValue} /><br/>
              <input type="submit" value="yeah boy" />
           </form>
       </div>
       );
     }
   }

 export default App;

Please guide me to building a FormData if it needs to be built and also if I still need to stringify it.

1 Answer 1

9

You're grabbing the image incorrectly, you need to use files, not value, like this:

this.setState({inputImageValue: event.target.files[0]})

Then to build FormData:

let formData = new FormData();
formData.append('pic1', event.target.myimage.files[0]);
formData.append('topstuff', event.target.topstuff.value);
formData.append('bottomstuff', event.target.bottomstuff.value);

And lastly remove JSON.stringify since you don't need that, and replace it with formData above

By the way: Since you're referring to your form's values directly via the DOM instead of via state you might want to consider:

  • getting rid of state all together
  • or start using state and start referring to the form's values via state
Sign up to request clarification or add additional context in comments.

4 Comments

Hi, Thanks. formData.append('myimage', event.target.myimage.files[0]); here, the first parameter myimage should represent the database column where the image is to be stored? my database column is called pic1. Is there a reason you used myimage there?
I used myimage here because that's what you used in your form, no other reason behind it, so you can change it to whatever you like. But whatever you change it to, that's the name that you will have to use on the server to refer to it.
Do I need the headers?
It will still work without them, but best practise is to specify them anyway, so I would leave them there

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.