0

I just started playing around with node.js (and javascript) and may have a fundamental misunderstanding. The following code works as expected. It is taken from a tutorial for a simple API with express, except for the extracted function to get the data (but the problem also occurs with restify except for a less informative stack trace).

var express = require('express');
var app = express();

var getdataandsend = function(request,response) {
        var res = {a:1,b:2}; // actually sql query using request.params
        response.send(res);
    }
app.get('/:id', function (request, response) {
    getdataandsend(request,response);});

var server = app.listen(1234, function () {});

However, since I only pass response to getandsenddata in order to call its send method, I figured that I might as well pass a reference/pointer to the method itself instead of the whole object:

var getdataandsend = function(request,respfun) {
        respfun({a:1,b:2}); 
    }
app.get('/:id', function (request, response) {
    getdataandsend(request,response.send);});

But this results in the following

TypeError: Cannot read property 'req' of undefined
   at send (...\test\node_modules\express\lib\response.js:103:17)
   at getdataandsend (...\test\misctest.js:6:9)
   at ...\test\misctest.js:9:6
   at Layer.handle [as handle_request] (...\test\node_modules\express\lib\router\layer.js:95:5)
...

The relevant line in response.js is var req = this.req;, which is the first occurence of a variable of that name in that file. Apparently, the value of this is different between the two calls above, even though the response object's method send is called from the same place (getdataandsend). Following this answer and that answer the observed behavior might make sense if the first call is considered a method and the second a function call, but why would that be the case? send is still a method of response, isn't it? Or are both function calls (...then what is response)?

Community
  • 1
  • 1

1 Answers1

1

In JavaScript, every function has a this object associated with it. This is used to store the data/execution context of the function.

In case of a constructor function or a method, the this object stores the public context of the object to which this method belongs.

However, if a function is not a constructor or a method, then the this object stores the global context, which is window in case of the browser, and GLOBAL for NodeJS.

It is possible to set the this object of a function to any context by using the native call, apply or bind functions.

Link for more information


What happens in your case is that when you are sending the response.send function to the getdataandsend function, you are actually stripping the send function from the this context of the response object.

So, when the send function, internally, tries to access anything from the this context, it gets an undefined, and consequently an error.

Soubhik Mondal
  • 2,496
  • 1
  • 11
  • 18