0

From a college suggestion and following this answer

I'm trying to monkey patch res.send but I get the following error:

TypeError: Cannot read property 'req' of undefined

This is my code

const express = require('express')
const app = express()

app.use((req, res, next ) => {
    const oldSend = res.send;
    res.send = (data) => {
        console.log(data.length);
        oldSend(data);
    }
    next();
})
app.get('/', (req, res) => res.send('Hello World!'))

Full stacktrace:

Example app listening on port 3000!
undefined
TypeError: Cannot read property 'req' of undefined
    at send (/Users/code/js/hello/node_modules/express/lib/response.js:110:17)
    at ServerResponse.res.send (/Users/code/js/hello/index.js:8:9)
    at app.get (/Users/code/js/hello/index.js:12:32)
    at Layer.handle [as handle_request] (/Users/code/js/hello/node_modules/express/lib/router/layer.js:95:5)
    at next (/Users/code/js/hello/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/Users/code/js/hello/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/Users/code/js/hello/node_modules/express/lib/router/layer.js:95:5)
    at /Users/code/js/hello/node_modules/express/lib/router/index.js:281:22
    at Function.process_params (/Users/code/js/hello/node_modules/express/lib/router/index.js:335:12)
    at next (/Users/code/js/hello/node_modules/express/lib/router/index.js:275:10)

Where line 110 is:

res.send = function send(body) {
  var chunk = body;
  var encoding;
  var req = this.req; //<-- THIS 
  var type;

  // settings
  var app
....
OscarRyz
  • 196,001
  • 113
  • 385
  • 569

2 Answers2

5

It's because methods are not tied to their instances in JavaScript.

If you call a.fun(), inside the function code, this will initially be set to a. But this happens only because a appears in the method call: fun is otherwise an arbitrary function that has no relationship with a.

In your case, this should work:

oldSend.call(res, data);

The point of call() is to set this.

Laurent Perrin
  • 14,671
  • 5
  • 50
  • 49
0

Found the solution, the oldSend loses it's context(?)

If I add bind(res):

const oldSend = res.send.bind(res);

The problem is gone.

OscarRyz
  • 196,001
  • 113
  • 385
  • 569