Why am i getting a bad request while sending data through a form?

Advertisements

I have an post api route that registers a user which requires the fields of name, email, and password.

My route works because i already tried it in postman and the user is saved in my mongoDB collection.
So i assume the issue is in how i am sending the form.
Nevertheless i´ll paste my api block of code:

router.post('/', [
    check('name', 'Name is required')
        .not()
        .isEmpty(),
    check('email', 'Plese include a valid email').isEmail(),
    check('password', 'Please enter a password with 6 or more characters').isLength({ min: 6 })
],
    async (req, res) => {
        const errors = validationResult(req);
        if (!errors.isEmpty()) {
            return res.status(400).json({ errors: errors.array() }); //400 is for bad requests
        }


        const { name, email, password } = req.body;

        try {
            //See if user exists
            let user = await User.findOne({ email });
            if (user) {
                return res.status(400).json({ errors: [{ msg: 'User already exists' }] });
            }

            //Get users gravatar
            const avatar = gravatar.url(email, {
                s: '200',
                r: 'pg',
                d: 'mm'
            })

            user = new User({
                name,
                email,
                avatar,
                password
            });

            //Encrypt password
            const salt = await bcrypt.genSalt(10);
            user.password = await bcrypt.hash(password, salt);
            await user.save();

            //Return jsonwebtoken -> this for users to be logged in right after registration
            const payload = {
                user: {
                    id: user.id
                }
            }
            jwt.sign(
                payload,
                config.get('jwtSecret'),
                { expiresIn: 360000 }, //change to 3600 for production
                (err, token) => {
                    if (err) throw err;
                    res.json({ token });
                }
            )

        } catch (err) {
            console.error(err.message);
            res.status(500).send('Server Error');
        }


    });

module.exports = router;

And this is my component from which i am sending the data:

import React, { useState } from 'react'
import axios from 'axios'

//Material UI
import {Grid, Container, Box, Button, FormControl, InputLabel, Input, FormHelperText } from '@mui/material'

function Register() {
    
    const [ formData, setFormData ] = useState({
        name: '',
        email: '',
        password: '',
        password2: ''
    })

    const { name, email, password, password2 } = formData; 

    const onChange = e => setFormData({...formData, [e.target.name]: e.target.value})

    const onSubmit = async (e) => {
        e.preventDefault();
        if(password !== password2){
            console.log("Passwords do not match");
        } else {
            const newUser = {
                name: "",
                email: "",
                password: ""
            }

            try {
                const config = {
                    headers: {
                        'Content-Type': 'application/json'
                    }
                }

                const body = JSON.stringify(newUser);
                const res = await axios.post('http://localhost:3000/api/users', body, config)
                console.log(res.data)

            } catch (error) {
                console.error(error.response.data)
            }
        
        }
    }

    return (
    <Container>
        <Box p={4}>
            <Grid container  >
                <form onSubmit={e => onSubmit(e)}>
                    <Grid item md={12}>
                        <FormControl>
                            <InputLabel htmlFor="name">Name</InputLabel>
                            <Input 
                            type='text' 
                            id='name' 
                            name='name'
                            value={name}
                            onChange={e => onChange(e)}
                            />
                            <FormHelperText>Insert your complete name</FormHelperText>
                        </FormControl>
                    </Grid> 
                    <Grid item md={12}>
                        <FormControl>
                            <InputLabel htmlFor="email">Email</InputLabel>
                            <Input 
                            id='email' 
                            type='email' 
                            name='email'
                            value={email}
                            onChange={e => onChange(e)}
                            />
                            <FormHelperText>Insert your email</FormHelperText>
                        </FormControl>
                    </Grid>
                    <Grid item md={12}>    
                        <FormControl>
                            <InputLabel htmlFor="password">Password</InputLabel>
                            <Input 
                            id="password" 
                            type='password' 
                            name='password'
                            value={password}
                            onChange={e => onChange(e)}
                            />
                            <FormHelperText>Insert your password (must have at least 6 characters)</FormHelperText>
                        </FormControl>
                    </Grid>
                    <Grid item md={12}>    
                        <FormControl>
                            <InputLabel htmlFor="password2">Confirm Password</InputLabel>
                            <Input 
                            id="password2" 
                            type='password'
                            name='password2' 
                            value={password2}
                            onChange={e => onChange(e)}
                            />
                            <FormHelperText>Insert your password (must have at least 6 characters)</FormHelperText>
                        </FormControl>
                    </Grid>
                    <Grid item md={12}>    
                        <Button type='submit' variant="contained" color="primary">
                            Register
                        </Button>
                    </Grid>
                </form>
            </Grid>
        </Box>
    </Container>
  )
}

export default Register

I don´t know if i am sending wrongly the data in the request i am making or it has to do with how i am doing the form with Material UI. Am i missing anything while sending the form?

As i send the form i get the array of errors in my console:

Object { errors: (3) […] }

0: Object { msg: "Name is required", param: "name", location: "body", … }
​​​
location: "body"
​​​
msg: "Name is required"
​​​
param: "name"
​​​
value: ""
​​​
<prototype>: Object { … }
​​
1: Object { msg: "Plese include a valid email", param: "email", location: "body", … }
​​
2: Object { msg: "Please enter a password with 6 or more characters", param: "password", location: "body", … }
​​

​​

​​

>Solution :

You are not sending over your form data, you basically have

const newUser = {
    name: "",
    email: "",
    password: ""
}
const body = JSON.stringify(newUser);
const res = await axios.post('http://localhost:3000/api/users', body, config)

Surely this should be

const newUser = {
    name: formData.name,
    email: formData.email,
    password: formData.password
}

Leave a ReplyCancel reply