Reputation: 983
I am trying to implement user authentication in a MERN stack app.
Here is what I am trying to do:
I have a registration form at the frontend. When a user registers for a second time with the same email ID as the first time, a message saying "User already registered" should be displayed at the front end at the top of the registration form. I am sending back this response ("User already registered") in JSON format from the backend with an error code of 400. The code is shown below.
const express = require('express');
const asyncHandler = require('express-async-handler');
const User = require('../models/userModel');
const generateToken = require('../utils/generateToken');
const router = express.Router();
router.post('/', asyncHandler(async (req, res, next) => {
const {name, email, password} = req.body;
const userExists = await User.findOne({email});
if(userExists) {
res.status(400).json({message: 'User already registered'});
}
const user = await User.create({
name,
email,
password
})
if(user) {
res.status(201).json({
_id: user._id,
name: user.name,
token: generateToken(user._id)
})
} else {
res.json({message: 'Invalid user data'});
}
}));
module.exports = router;
The problem I am facing is, instead of showing "User already registered", the message that gets displayed is "Request failed with status code of 400".
When I check the Network tab, I see that the message "User already registered" is coming back from the server as the response.
The following is the complete code for the registration form.
import React, {useState} from 'react'
import {useFormik} from 'formik'
import * as Yup from 'yup';
import axios from 'axios';
const RegisterScreen = ({history}) => {
const [error, setError] = useState(null);
const formik = useFormik({
initialValues: {
name: '',
email: '',
password: "",
},
validationSchema: Yup.object({
name: Yup.string()
.max(15, 'Must be 15 characters or less')
.required('Required'),
email: Yup.string()
.email('Invalid email address')
.required('Required'),
password: Yup.string()
.required('Required')
}),
onSubmit: async (values, {resetForm}) => {
try {
const response = await axios.post('/api/users', values);
history.push('/login');
} catch (ex) {
console.error(ex);
setError(ex);
}
},
});
return (
<form onSubmit={formik.handleSubmit}>
<div className="form-group col-md-4 mx-auto mt-5">
{error && <div className="alert alert-danger" role="alert">{error.message}</div>}
<label htmlFor="firstName">Name</label>
<input
className="form-control"
id="name"
name="name"
type="text"
onChange={formik.handleChange}
onBlur={formik.handleBlur}
value={formik.values.name}
/>
{formik.touched.name && formik.errors.name ? <small className="form-text text-danger">{formik.errors.name}</small>:null}
</div>
<div className="form-group col-md-4 mx-auto">
<label htmlFor="email">Email Address</label>
<input
className="form-control"
id="email"
name="email"
type="email"
onChange={formik.handleChange}
onBlur={formik.handleBlur}
value={formik.values.email}
/>
{formik.touched.email && formik.errors.email ? <small className="form-text text-danger">{formik.errors.email}</small>:null}
</div>
<div className="form-group col-md-4 mx-auto">
<label htmlFor="password">Password</label>
<input
className="form-control"
id="password"
name="password"
type="text"
onChange={formik.handleChange}
onBlur={formik.handleBlur}
value={formik.values.password}
/>
{formik.touched.password && formik.errors.password ? <small className="form-text text-danger">{formik.errors.password}</small>:null}
</div>
<div className="col-md-4 mx-auto">
<button type="submit" className="btn btn-primary">Register</button>
</div>
</form>
);
};
export default RegisterScreen;
What am I doing wrong? I want "User already registered" to be displayed, not "Request failed with status code 400".
Upvotes: 0
Views: 414
Reputation: 678
Your error message will be at
error.response.data.message
Not at
error.message
In Axios you can get json data you sent from server in error.response.data
Here is link to handle errors with axios
Upvotes: 2