0
votes

Hi, I have some troubles with sending all data in my request using axios. I created node.js api and now I want to send user registration data from my form using axios and react js as my frontend technology.

I updated my state in react after submit and now when I want to send information by 'Content-Type': 'application/x-www-form-urlencoded' my firstName is not send(null) and last value- location get '\"' at the end.

I tested request in postman and it works well.

Any advice?

my node.js route:

app.post('/users', (req, res) => {

      const user = { firstName: req.body.firstName, lastName: req.body.lastName, age: req.body.age, photo: req.body.photo, email: req.body.email, description: req.body.description, hobbies: req.body.hobbies, location: req.body.location };

      db.collection('users').insert(user, (err, result) => {
        if (err) { 
          res.send({ 'error': 'An error has occurred' }); 
        } else {
          res.send(result.ops[0]);
        }
      });
    });

react registration:

import React, { Component } from 'react';
import axios from 'axios';

class Register extends Component {
    state = {
        firstName: '',
        lastName: '',
        age: '',
        email: '',
        description: '',
        hobbies: '',
        location: '',
    };

    handleFirstNameChange = event => {
        this.setState({ 
            firstName: event.target.value,
        });
    }

    handleLastNameChange = event => {
        this.setState({ 
            lastName: event.target.value,
        });
    }

    handleEmailChange = event => {
        this.setState({ 
            email: event.target.value,
        });
    }

    handleAgeChange = event => {
        this.setState({ 
            age: event.target.value,
        });
    }

    handleDescriptionChange = event => {
        this.setState({ 
            description: event.target.value,
        });
    }

    handleHobbiesChange = event => {
        this.setState({ 
            hobbies: event.target.value,
        });
    }
    handleLocationChange = event => {
        this.setState({ 
            location: event.target.value,
        });
    }

    handleSubmit = event => {
        event.preventDefault();

        const user = {
            firstName: this.state.firstName,
            lastName: this.state.lastName,
            age: this.state.age,
            email: this.state.email,
            description: this.state.description,
            hobbies: this.state.hobbies,
            location: this.state.location,
        };

        //x-www-form 
        let formBody = [];
        for (let property in user) {
            let encodedKey = encodeURIComponent(property);
            let encodedValue = encodeURIComponent(user[property]);
            formBody.push(encodedKey + "=" + encodedValue);
        }
        formBody = formBody.join("&");

        console.log(formBody);

        axios.post(`http://localhost:8000/users`, { formBody }, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } })
          .then(res => {
            console.log(res);
            console.log(res.data);
        })
    }

  render() {
    return (
      <div className="register">
        <h2>Register</h2>

        <form onSubmit={this.handleSubmit}>
            <label htmlFor="firstName">First Name:</label>
            <input type="text" id="firstName" name="firstName" onChange={this.handleFirstNameChange} />
            <br/>
            <label htmlFor="lastName">Last Name:</label>
            <input type="text" id="lastName" name="lastName" onChange={this.handleLastNameChange} />
            <br/>
            <label htmlFor="email">Email:</label>
            <input type="text" id="email" name="email" onChange={this.handleEmailChange} />
            <br/>
            <label htmlFor="age">Age:</label>
            <input type="text" id="age" name="age" onChange={this.handleAgeChange} />
            <br/>
            <label htmlFor="description">Description of myself:</label>
            <input type="text" id="description" name="description" onChange={this.handleDescriptionChange} />
            <br/>
            <label htmlFor="hobbies">Hobbies:</label>
            <input type="text" id="hobbies" name="hobbies" onChange={this.handleHobbiesChange} />
            <br/>
            <label htmlFor="location">Location:</label>
            <input type="text" id="location" name="location" onChange={this.handleLocationChange} />
            <br/>
            <input type="submit" value="Register" />
        </form>

      </div>
    );
  }
}

export default Register;

database result in mLab:

{
    "_id": {
        "$oid": "5b3af97a10d5b622289ddbbc"
    },
    "firstName": null,
    "lastName": "test",
    "age": "222",
    "photo": null,
    "email": "[email protected]",
    "description": "test",
    "hobbies": "test",
    "location": "test\"}"
}
3
Thank you guys for smart answers. I really appreciate your help. I also noticed that trouble with my code was add { formBody } instead of just formBody without curly brackets in axios code. Awesome answers, thank you. - MarkFroog
Why would we use axios to make requests to a node.js server when we can use axios to make requests directly? - readytotaste

3 Answers

0
votes

There is a URLSearchParams class for this:

const params = new URLSearchParams();
params.append('param1', 'value1');
params.append('param2', 'value2');
axios.post('/foo', params);
0
votes

You can modify your code like this below, You can minimise your code with the help of libraries like https://underscorejs.org/

//nodejs route
import _ from "underscore";
app.post('/users', (req, res) => {
    //const user = { firstName: req.body.firstName, lastName: req.body.lastName, age: req.body.age, photo: req.body.photo, email: req.body.email, description: req.body.description, hobbies: req.body.hobbies, location: req.body.location };
    const user = _.pick(req.body, 'firstName', 'lastName', 'email', 'age', 'description', 'hobbies', 'location')
    db.collection('users').insert(user, (err, result) => {
        if (err) {
            res.send({ 'error': 'An error has occurred' });
        } else {
            res.send(result.ops[0]);
        }
    });
});

//React Registration    
import React, { Component } from 'react';
import axios from 'axios';

class Register extends Component {
    state = {
        firstName: '',
        lastName: '',
        age: '',
        email: '',
        description: '',
        hobbies: '',
        location: '',
    };

    handleChange = event => {
        const { name, value } = event.target  //Destructure the current fields name and value
        this.setState({ [name]: value });  //Sets state
    };

    handleSubmit = event => {
        event.preventDefault();
        //Alter your Axios request like below
        axios({
            method: 'post',
            url: 'http://localhost:8000/users',
            headers: {
                'crossDomain': true,  //For cors errors 
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            data: {
                firstName: this.state.firstName,
                lastName: this.state.lastName,
                age: this.state.age,
                email: this.state.email,
                description: this.state.description,
                hobbies: this.state.hobbies,
                location: this.state.location,
            }
        }).then(res => {
            console.log(res);
            console.log(res.data);
        });
    }   

    render() {
        return (
            <div className="register">
                <h2>Register</h2>

                <form onSubmit={this.handleSubmit}>
                    <label htmlFor="firstName">First Name:</label>
                    <input type="text" id="firstName" name="firstName" onChange={this.handleChange} />
                    <br />
                    <label htmlFor="lastName">Last Name:</label>
                    <input type="text" id="lastName" name="lastName" onChange={this.handleChange} />
                    <br />
                    <label htmlFor="email">Email:</label>
                    <input type="text" id="email" name="email" onChange={this.handleChange} />
                    <br />
                    <label htmlFor="age">Age:</label>
                    <input type="text" id="age" name="age" onChange={this.handleChange} />
                    <br />
                    <label htmlFor="description">Description of myself:</label>
                    <input type="text" id="description" name="description" onChange={this.handleChange} />
                    <br />
                    <label htmlFor="hobbies">Hobbies:</label>
                    <input type="text" id="hobbies" name="hobbies" onChange={this.handleChange} />
                    <br />
                    <label htmlFor="location">Location:</label>
                    <input type="text" id="location" name="location" onChange={this.handleChange} />
                    <br />
                    <input type="submit" value="Register" />
                </form>

            </div>
        );
    }
}

export default Register;
0
votes

When type is Content-Type': 'application/x-www-form-urlencoded, you must parse your object data to string urlencoded

You can use lib qs to stringify your data before send:

const dataSend = qs.stringify(user);

import qs from "qs";

    app.post('/users', (req, res) => {

          const user = { firstName: req.body.firstName, lastName: req.body.lastName, age: req.body.age, photo: req.body.photo, email: req.body.email, description: req.body.description, hobbies: req.body.hobbies, location: req.body.location };

          const dataSend = qs.stringify(user);

          db.collection('users').insert(dataSend, (err, result) => {
            if (err) { 
              res.send({ 'error': 'An error has occurred' }); 
            } else {
              res.send(result.ops[0]);
            }
          });
        });