I am using node v0.11.14-nightly-20140819-pre on Windows with harmony
flag.
I have JavaScript object with two methods defined in its prototype:
function User (args) {
this.service= new Service(args);
}
User.prototype.method2 = function (response) {
console.log(this); // <= UNDEFINED!!!!
};
User.prototype.method1 = function () {
.............
this.service.serviceMethod(args)
.then(this.method2)
.catch(onRejected);
};
function onRejected(val) {
console.log(val);
}
serviceMethod
of Service
object returns a promise.
When I use User
object like below:
let user = new User(args);
user.method1();
this
in method2
of object User
ends up undefined
when called by then
once promise is fulfilled.
I tried using both ES6 and Bluebird promise implementation.
Why this
ends up being undefined
in this case?
Why this
ends up being undefined
in this case?
Because you\'re passing a function, not a method-bound-to-an-instance. This problem is not even promise-specific, see How to access the correct `this` context inside a callback? for the generic solution:
….then(this.method2.bind(this))… // ES5 .bind() Function method
….then((r) => this.method2(r))… // ES6 arrow function
However, Bluebird does offer an other way to call the function as a method:
this.service.serviceMethod(args)
.bind(this)
.then(this.method2)
.catch(onRejected);
I should add that this is a generic Javascript issue and can also be solved using plain javascript features. For example, you could also do this:
User.prototype.method1 = function () {
.............
this.service.serviceMethod(args)
.then(this.method2.bind(this))
.catch(onRejected);
};
This uses Function.prototype.bind()
which is built into Javascript and present on every function. This creates a function stub (which is what is passed to .then()
and that stub will automatically reattach the desired this
value before calling method2()
.