So I know there are tons of similar questions out there, and I’ve read most of them in the past few days. However I didn’t find any solution to my problem. The app is about users can post memories(cards) etc… Point is, when I create a new card with POST request, there is no problem, but when I want to sign up a user then all hell breaks loose and throws this error:
(node:2732) UnhandledPromiseRejectionWarning: TypeError: Cannot destructure property ‘firstName’ of ‘req.body’ as it is undefined. at signup (file:///E:/projects/personal/memories-app/backend/controllers/user.controller.js:39:13) at Layer.handle [as handle_request] (E:projectspersonalmemories-appbackendnode_modulesexpresslibrouterlayer.js:95:5) at next (E:projectspersonalmemories-appbackendnode_modulesexpresslibrouterroute.js:137:13)
I don’t know that could be the problem, because other functions work so dunno really. Here are the codes
server.js
import express from 'express';
import mongoose from 'mongoose';
import cors from 'cors';
import dotenv from 'dotenv';
import postRoutes from './routes/posts.routes.js';
import userRoutes from './routes/users.routes.js';
const app = express();
dotenv.config();
app.use(express.json({ extended: true }));
app.use(express.urlencoded({ extended: true }));
app.use(cors());
app.use('/posts', postRoutes);
app.use('/users', userRoutes);
app.get('/', (req, res) => {
res.send('Hello to Memories API');
});
const PORT = process.env.PORT || 5000;
mongoose
.connect(process.env.CONNECTION_URL, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() =>
app.listen(PORT, () => console.log(`Server running on port: ${PORT}`))
)
.catch((error) => console.log(error.message));
mongoose.set('useFindAndModify', false);
user.model.js
import mongoose from 'mongoose';
const userSchema = mongoose.Schema({
name: { type: String, required: true },
email: { type: String, required: true },
password: { type: String, required: true },
id: { type: String },
});
export default mongoose.model('User', userSchema);
the sign up method from user.controller.js
import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken';
import User from '../models/user.js';
export const signup = async (res, req) => {
const { firstName, lastName, email, password, confirmPassword } = req.body;
try {
const existingUser = await User.findOne({ email });
if (existingUser)
return res.status(400).json({ message: 'User already exists' });
if (password !== confirmPassword)
return res.status(400).json({ message: "Passwords don't match" });
const hashedPassword = await bcrypt.hash(password, 12);
const result = await User.create({
email,
password: hashedPassword,
name: `${firstName} ${lastName}`,
});
const token = jwt.sign(
{ email: result.email, id: result._id },
'test',
{
expiresIn: '1h',
}
);
res.status(200).json({ result, token });
} catch (error) {
res.status(500).json({ message: 'Something went wrong.' });
}
};
and just to see the createPost method (which works) from post.controller.js
import PostMessage from '../models/postMessage.js';
import mongoose from 'mongoose';
export const createPost = async (req, res) => {
const post = req.body;
console.log(post);
const newPost = new PostMessage(post);
try {
await newPost.save();
res.status(201).json(newPost);
} catch (error) {
res.status(409).json({ message: error.message });
}
};
And there is no problem with the front-end because when I simply console.log the req, I can see the body, but if I were to clg the req.body, then it is undefined. I’ve tried it with postman also, but no luck.
I would appreciate any insight on this! Thanks in advance!
Advertisement
Answer
You need to swap the order of res
and req
in the signup
function, replace:
export const signup = async (res, req) => {
by:
export const signup = async (req, res) => {