Ad

GitHub Fetch Polyfill Does Not Summit Form Body With React Form Componet

- 1 answer

I am using the fetch api polyfill by GitHub with React. The example for submitting a form is as follows:

var form = document.querySelector('form')

fetch('/users', {
    method: 'post',
    body: new FormData(form)
})

My code currently looks something like this inside the component

handleSubmit (event) {
    event.preventDefault();

    fetch('/api/user/', {
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        method: 'post',
        body: JSON.stringify(this.state)
    }).then(function(response) {
        console.log(response);
    })
},

In the app state I am holding the data being sent. It's a simple object.

{
    email: '[email protected]',
    password: 'password',
    name: 'Some Name'
}

I have tried passing the form itself from the event event.target as well as getting the form through an the ID attribute and passing it to the body.

On the server I am using NodeJs to catch the form body in the request. But the request is empty if I don't pass the header 'Content-Type': 'application/x-www-form-urlencoded'. But when I do pass it the entire body is the value with an empty key, but only when I use JSON.stringify(this.state). As follows:

'{email: '[email protected]',password: 'password',name: 'Some Name'}': ''

I have also tried passing no headers, and the following header.

headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
}

I am adding the fetch module through webpack as a plugin.

new webpack.ProvidePlugin({
    'Promise': 'exports?global.Promise!es6-promise',
    'fetch': 'imports?this=>global!exports?global.fetch!whatwg-fetch'
})

I'm stuck, any help is appreciated.

Currently I have a really ugly hack on the server to convert the key=>value pair into an object again, but It's shameful event to share it.

var userInfo = req.body;
var tempVals;
//hack to fixed fetch
if(!userInfo.email) {
    for(values in req.body) {
        tempVals = JSON.parse(values);

        if(tempVals.email) {
            userInfo = tempVals;
            break;
        }
    }
}

...I said it was ugly.

UPDATE

Thanks to Michelle, I was able to figure figure out that it was something to do with parsing the form data. I used the body-parser module. I could not get the data to be read with my current set up. I had to change my code on the client side to as follows:

handleSubmit (e) {
    e.preventDefault();

    fetch('/api/user/', {
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        },
        method: 'post',
        body:  JSON.stringify(this.state)
    }).then(function(response) {
        console.log(response);
    })
} 

and in the backend I had to add the JSON body parser to my route as follows

var bodyParser = require('body-parser');
var jsonParser = bodyParser.json();

app.post('/user', jsonParser, function(req, res) {
    //do something with the data
});
Ad

Answer

The example you posted:

var form = document.querySelector('form')

fetch('/users', {
    method: 'post',
    body: new FormData(form)
})

is the example for posting form data (see this Stack Overflow question for more information). You're trying to submit JSON data, and the very next example in the README is the method you should use:

fetch('/users', {
  method: 'post',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: 'Hubot',
    login: 'hubot',
  })
})

so your code would look like

handleSubmit (event) {
    event.preventDefault();

    fetch('/api/user/', {
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        },
        method: 'post',
        body: JSON.stringify(this.state)
    }).then(function(response) {
        console.log(response);
    })
},

You will also need to have appropriate middleware installed in your Express app to parse JSON bodies (for example, body-parser):

var bodyParser = require('body-parser');

// ...

app.use(bodyParser.json());

app.post('/user', function(req, res) {
    //do something with the data
});
Ad
source: stackoverflow.com
Ad