Francisco
Francisco

Reputation: 53

TypeError: Cannot read property 'get' of undefined on Express

I'm developing an app with express but I get this error:

 TypeError: Cannot read property 'get' of undefined

      45 |
      46 |   if (!validate.pass)
    > 47 |      return res.status(400).send(
         |                             ^
      48 |              response(false, validate.errors, 'Error in request.')
      49 |      )
      50 |

      at ServerResponse.json (node_modules/express/lib/response.js:257:20)
      at ServerResponse.send (node_modules/express/lib/response.js:158:21)
      at Object.create (controllers/rideController.js:47:27)
      at Object.<anonymous> (__test__/rideController.test.js:32:10)

I don't get why get method is involved if I'm summoning send method.

The call of this is:

const res = require('express').response
...
ride.create({body: data}, res)

The functions are:

const rideRules = {
  rider: 'required|user',
  passenger: 'required|array',
  seats: 'required|integer',
  start_location: 'required|string',
  destination: 'required|string'
}

const errorsMessage = {
  'required.rider': "El conductor es necesario.",
  'required.passenger': "Los pasajeros son necesarios.",
  'required.seats': "El número de asientos disponibles es necesario.",
  'start_location': "El lugar de partida es necesario.",
  'destination': "El lugar de destino es necesario."
}

const create = (dataRide) => {
  const { rider, passenger, seats, start_location, destination } = dataRide
  return rides.create({
    rider: rider,
    passenger: passenger,
    available_seats: seats,
    status: 'En progreso',
    start_location: start_location,
    destination: destination,
    time: new Date(),
    ride_finished: false,
    comment: [{}]
  })
}

exports.create = (req, res) => {
  const validate = validateIn(req.body, rideRules, errorsMessage)

  if (!validate.pass) 
    return res.status(400).send(
        response(false, validate.errors, 'Error in request.')
    )

  const rideInf = create(req.body)

  return res.status(200).send(response(true, rideInf, 'Ride created.'))
}

What I want is an unit test of create function.

The first problem I found was how to simulate a request and a response. As all I do with the request is using the property body I use a json and there's no more problem with this.

The current problem is the response.

Upvotes: 0

Views: 2783

Answers (1)

jfriend00
jfriend00

Reputation: 707426

Whatever you are attempting to do with this:

const res = require('express').response

looks misguided. The .response property on the Express object is not a live response object. If you look at the appropriate part of the Express code, you can see that require('express').response is the response module (and all the things that it exports). These are methods that will be used on a live response object, but are not yet on a live response object. These are just exported methods that will eventually be attached to a live response object. You can't use them in this way until they are attached to a live response object.

If you look further into ./response.js in the Express project, you see that require('express').response is actually a prototype derived from http.ServerResponse.prototype that Express will use later when it creates a live response object.

When you actually call res.send() on this prototype version of res, it appears that the first method it may actually call is in this section of code:

  if (!this.get('Content-Type')) {

Since this is incorrect when attempting to use the prototype this way, there would be no .get() method and you'd get the error you see.


Thus, when you then try to use that res object in the way that you would use a live response object, you will get some sort of error. We'd have to be able to debug your exact code to explain why it complains exactly the way it does (perhaps there is a getter involved and thus the error message references get - that's just a guess). But, it's fairly clear that res is not being used correctly.

If you show more of the context of your code (including the whole request handler), we can make more of a suggestion for how it should be written. If you want more details on why the error comes out exactly the way it does, we'd need to be able to actually run that portion of your code to debug it and see what precisely is happening. In any case, you need to change where you get res from.


To test your create() function that uses an http response object, you can either make a real http response object (involving a real http request/response) or create a mock http response object and hook the appropriate methods to see if the function does what it is supposed to. You can read any number of articles here on various ideas for mocking an http response object.

Upvotes: 1

Related Questions