Node js pass context for callback

I am using node.js. I have this handlers.js file:

exports.Handlers = function(prefix) { this.prefix = prefix; this.db = new DBInstance(); }; exports.Handlers.prototype.getItemById = function(id) { var item = this.db.getItemById(id, function(error, item) { item.name = this.prefix + item.name; ... ... }); }; 

When i call:

 var h = new Handlers(); h.getItemById(5); 

I get an error because the context is not a handler and this.prefix does not exist. I can fix this using this:

 exports.Handlers.prototype.getItemById = function(id) { var scope = this; var item = this.db.getItemById(id, function(error, item) { item.name = scope.prefix + item.name; ... ... }); }; 

Is there a better way to pass context for a callback? What is the general nodejs method for passing the callback context?

+4
source share
3 answers

Node implements ECMAScript 5, which has Function.bind() .

I think this is what you are looking for.

 exports.Handlers.prototype.getItemById = function(id) { var item = this.db.getItemById(id, (function(error, item) { item.name = this.prefix + item.name; ... ... }).bind(this)); //bind context to function }; 

This works, however, when using a closure as a callback, like you, the most common way is to save the context in a variable that can be used in closure.

This method is more common, because many times callbacks can be deep, and bind for each callback can be heavy; whereas defining self once is easy:

 SomeObject.prototype.method = function(id, cb) { var self = this; this.getSomething(id, function(something) { //self is still in scope self.getSomethingElse(something.id, function(selse) { //self is still in scope and I didn't need to bind twice self.gotThemAll(selse.id, cb); }); }); }; 
+15
source

This problem is not related to Node.js, it is a common problem in JavaScript - and you already figured out the usual solution in JavaScript: bind this context to another variable (the one you called scope ) and use this in a callback to access the external context .

Common names for this variable include that and self .

In ECMAScript 6 (code-named "harmony"), there may be a solution with the so-called bold arrow operator, which associates a function with an external context. If you want to play with him today, you can check out TypeScript , a pre-compiler for JavaScript made by Microsoft that focuses on ES6 compatible syntax. Then your callback will become something like

 foo(() => { console.log(this.bar); }); 

instead:

 var that = this; foo(function () { console.log(that.bar); }); 

For completeness only: the jQuery function (and other frameworks) of bind usually works the same way. See http://api.jquery.com/bind/ for an example.

NTN.

+1
source

This is the usual way. You will find your scope var named self or _self .

Next edit:

If you want to call a function in a different context, this is the way:

 getItemById.call(context, vars); 
-1
source

All Articles