1

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: 'test@test.com',
        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":"test@email.com",
    "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)

shonacoder
  • 61
  • 6
  • 1
    Do you have the body-parser middleware installed on this express project? – Mooshua Apr 22 '22 at 17:23
  • Yes, I do. From reading similar posts I have switched to using app.use(express.json()) instead though. – shonacoder Apr 22 '22 at 17:25
  • Some prior middleware has to read the body and parse it into `req.body` otherwise `req.body` is empty and the body hasn't yet been read from the incoming http stream. For Express and a JSON content-type body, that would be `app.use(express.json())` as a middleware statement BEFORE your signup route is declared. – jfriend00 Apr 22 '22 at 17:28
  • Thank you! This is my main app.js file and it's where the middleware is registered. I do have the middleware statement before my signup route is declared but it's not getting those destructured values: name, email and password correctly. – shonacoder Apr 22 '22 at 17:31
  • What is the incoming `content-type`? You can do `console.log(req.headers)` to see. If it's not `application/json`, then `express.json()` won't touch it. – jfriend00 Apr 22 '22 at 18:11

1 Answers1

0

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/

  • 1
    This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/late-answers/33942378) – dostogircse171 Mar 05 '23 at 21:57