How to store the contents of the request body correctly in Express middleware of POST request

1k views Asked by At

I have a middleware in my React Express project that stores a new user that is created as follows:

const uuid = require('uuid/v4')

const HttpError = require('../models/http-error')

let DUMMY_USERS = [
    {
        id: 'u1',
        name: 'tanaka',
        email: '[email protected]',
        password: 'test'
    }
]

const signup = (req, res, next) => {
    const { name, email, password } = req.body;
    const users = DUMMY_USERS
    const hasUser = DUMMY_USERS.find(u => u.email === email);
    console.log('hasUser ->',hasUser)
    if (hasUser) {
        throw new HttpError('Could not create user, email already exists.', 422);
    }

  const createdUser = {
    id: uuid(),
    name, 
    email,
    password
  };

  users.push(createdUser);

  res.status(201).json({user: createdUser});
};

The middleware is registered on the express Router object as follows:

router.post('/signup', usersControllers.signup)

When I save a new user through Postman by hitting the endpoint http://localhost:5000/api/users/signup with the following body:

{
    "name":"test",
    "email":"[email protected]",
    "password":"test",
}

the body that is saved is as follows:

{
    "user": {
        "id": "e8a4fe92-0ff1-452e-ba3f-4145289b26d7"
    }
}

and when I log the createdUser object, I get undefined values for name, email and password. Why are these destructured values being set to undefined?

Updated to show app.use(express.json()) to parse response body before registering middleware:

The signup middleware is exported into usersRoutes which is registered in app.js below.

const express = require('express')

const HttpError = require('./models/http-error')
const placesRoutes = require('./routes/places-routes')
const usersRoutes = require('./routes/users-routes')
const app = express()

app.use(express.json())

app.use('/api/places', placesRoutes)

app.use('/api/users', usersRoutes)

// middleware to handle unsupported routes
app.use((req, res, next) => {
    const error = new HttpError('Could not find this route.', 404)
    throw error // could call it as next(error) if this were in asynchronous code eg. communication with the database
})

//error handling middleware
app.use((error, req, res, next) => {
    if (res.headersSent) {
        return next(error)
    }
    res.status(error.code || 500)
    res.json({message: error.message || 'An unknown error occured!'})
})

app.listen(5000)

1

There are 1 answers

1
ericktreichel On

It's just like jfriend00 commented above: you probably set content-type to multipart/form-data in order to handle the files, but doing so you lost the ability to parse the body as a json. I got myself in the exactly situation as you an honestly I couldn't find any good way to solve this. Now I'm trying to solve this by 'wraping' my body content in a Blob in the frontend, then sending only files to the backend (the usual files from my input, such as images, videos or whatever, and the blob as a file too). So now I'm just figuring out how to capture this blob in the backend, then 'unwrap' it in order to access the content inside it as my body. Do not hesitate contacting me if you find any better solution for this problem. Thanks o/