Working with Form Data in React
Welcome back to the course. In this guide, we're going to talk about form data, specifically the image input, because we haven't handled that one yet.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

What we need do is we need to go to the image input and refactor a bit, but before we do that let's go to our requestsNew.js and talk about form data. What we need to do is provide form data to our back-end instead of just straight JSON. So let's say:

requestsNew.js

  onSubmit = fields => {
    // if(button == 'submit') {
    //   // save new newsletter on the backend. perform a post request here.
    //   console.log('trying to submit to backend.');
    // }

    var formData = new FormData();
    formData.append('title');
    this.props.createNewRequest(this.props._id, {}, () => {
        this.props.history.push("/dashboard");
    })

  };

Now, in order to get this title, we need to get it from fields. Let's just get all of our pieces of data out like this. Let's just get rid of this comment real quick, and let's say:

requestsNew.js

  onSubmit = fields => {

    const { title, body, image } = fields;

    var formData = new FormData();
    formData.append('title');

    this.props.createNewRequest(this.props._id, fields, () => {
        this.props.history.push("/dashboard");
    })

  };

Right now, this isn't going to work with image because we're not actually getting access to the image yet. We're not doing it properly in our formFields.js component for the form image. With that in mind, let's just quickly put in the title, and then let's say:

requestsNew.js

  onSubmit = fields => {

    const { title, body, image } = fields;

    var formData = new FormData();
    formData.append('title', title);
    formData.append('body', body);
    formData.append('image', image);

    this.props.createNewRequest(this.props._id, fields, () => {
        this.props.history.push("/dashboard");
    })

  };

Let's quickly console.log image and see what we get. Let's console.log all of these, and comment out createNewRequest because we don't want to call this again yet.

requestsNew.js

  onSubmit = fields => {

    const { title, body, image } = fields;

    var formData = new FormData();
    formData.append('title', title);
    formData.append('body', body);
    formData.append('image', image);

    console.log(title, body, image);

    // this.props.createNewRequest(this.props._id, fields, () => {
    //     this.props.history.push("/dashboard");
    // })

  };

Everything that we've done in this video is in this onSubmit function. Let's go to the browser and log in, let's go to requests, let's create a new request, type some stuff in here, and select an image. I just took a screenshot of my background so that it could be a small image.

We want something small just to test with. That's just a part of my background. We have this console.log, let's type this out, let's choose an image, and hit submit. You'll see it prints the title and the body, but not the image. It says undefined for the image. We need to see a file there.

large

We don't want to see undefined. Let's go to our code and let's go to formFields.js. Let's scroll down to form-image, it looks like we are there. What we need to do is simply, you'll see that we've commented out id='' here, uncomment that and type in a very specific string for this to work.

That string is loadFileXml, so let's say id='loadFileXml'. Actually, I don't think this is why, so my bad, you won't see this. It won't work, I know. It's still undefined, so you can get rid of that string.

What we need to do is we need to refactor our handleSelectedImage function, because right now, all it's doing is putting it into the image. We're not actually doing anything else with the file. What we need to do is pass it back up to our onChange function for the field for Redux-Form.

This would work if this was a normal form, but since this is using Redux-Form we need to do a couple of things. We need to say:

formFields.js

    handleSelectedImage = (event) => {
        const { onChange } = this.props;
        var image = document.getElementById('newsletter-new-image');
        image.src = URL.createObjectURL(event.target.files[0]);
        onChange(event.target.files[0])
    }

We're putting it in the image and we're also sending it back up through our field to Redux-Form. Let's go to the application, let's login, let's go to requests, create a new request, let's type some junk in here, let's select an image, and let's hit submit.

It says onChange is not a function. The reason it's doing that is because we need to bind this.

large

We need write a constructor and say:

formFields.js

    constructor() {
        super()

        this.handleSelectedImage = this.handleSelectedImage.bind(this);
    }

Now what we need to do is go back there and see what happens when we do it. Go to requests, new request, and let's select an image. It's still saying that onChange is not a function. It could be because of the way we're writing the function because they all react differently. No pun intended.

I think I know what going on, onChange isn't part of our props. We probably don't even need this constructor. We will hit command + z if we do. So onChange comes from the input, which is in props. We actually need to get input and then within input, we need onChange.

formFields.js

    handleSelectedImage = (event) => {
        const { input: { onChange } } = this.props;
        var image = document.getElementById('newsletter-new-image');
        image.src = URL.createObjectURL(event.target.files[0]);
        onChange(event.target.files[0])
    }

It's kind of like two levels of pulling it out. What we need to do is we need to go into the application and try it out. Now, you'll see we have access to our file. That's awesome.

large

Now we can put it in our form data and we'll be good to go. Actually, it is in our from date at this point because you know that in our requestNew.js we have all this form data. We put it in, and then we just printed out each item, which means they're all in here too.

What we need to do now is create the new request and perform the GET request to the server, POST request. Let's commit our code, and in the next video, we'll talk more about this. Let's say git status, git add ., and let's say git commit -m "formdata and input onchange".

Resources