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) => {