Errol Dsilva
Errol Dsilva

Reputation: 177

Issue with variable scope in NodeJS, Express, Prototyping

File: MainApp.js

var reqHandler = reqire('HTTPRequestPostHandler')..
...
...
var httpRequestHandler = new reqHandler();


app.post('/', httpRequestHandler.handleRootPost);

File: HTTPRequestPostHandler.js

HTTPRequestPostHandler =function(){
   this.someVar = value;
}
HTTPRequestPostHandler.prototype.handleRootPost{
     console.log(this.someVar) //Error -> this.someVar is undefined.

}

I have these 2 files. The MainApp.js is where express is configured and various handlers for each endpoints e.g. '/'.

But when a post request occurs and the request handler (HTTPRequestPostHandler.prototype.handleRootPost) is invoked, I get a undefined error while accessing the variable this.someVar.

Why is this happening. What am I doing wrong here.

Upvotes: 0

Views: 131

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074028

It's not a scope issue, it's a this issue.

Normally in JavaScript, this is set entirely by how a function is called, not where it's defined. So what's happening is you're passing your method in as a callback, but since it's not being called in a way that sets this to be your instance. (The next version of the specification, ES6, will have "arrow functions" that have this bound to them rather than being set by how they're called.)

The usual way that this gets set during a function call is when you call the function as part of an expression retrieving the function reference from an object, e.g.

foo.bar();

That calls bar with this set to foo. But this:

var f = foo.bar;
f();

...does not. this will be undefined (in strict mode) or the global object (in loose mode).

Other ways to set this are via Function#call and Function#apply, which let you call the function and explicitly say what this should be.

You can solve this with bind:

app.post('/', httpRequestHandler.handleRootPost.bind(httpRequestHandler));

bind returns a function that, when called, will call the original function with this set to what you pass in as the first argument.

More (on my blog):

Upvotes: 5

Related Questions