ES6 and variable scope inside a promise
Solution 1
You need to do two things. First, use an arrow function, and second, use `this.contact = data;
activate(id) {
this.id = id;
return dpd.contacts.get(id).then(data => {
console.log(data);
this.contact = data;
});
}
You use an arrow function because it deals with JavaScript's "this
" issue, where this refers to the lexical scope of the function, and not the object you're currently in. Using an arrow function makes sure that this
outside the arrow function is the same as this
inside the arrow function.
You need to use this.contact
because contact
is an instance property of the class.
Solution 2
The problem is that contact = data;
will update the value of the local contact
variable, but will not change the value of the this.contact
.
You need to update the contact
contact property instead. The problem is that you do not have access to this
inside the body of your anonymous function (or rather, the this
of the anonymous function is not going to be the same this
as activate
's).
There is different ways to solve this.
1- You can save activate's context (this
) into a variable in the closure of activate
so that you can access it inside the core of then
.
activate(id) {
this.id = id;
let that = this;
return dpd.contacts.get(id).then(function(data) {
console.log(data);
that.contact = data;
});
}
2- You can bind the function to activate
's this
so that it is called with the same context.
activate(id) {
this.id = id;
return dpd.contacts.get(id).then(function(data) {
console.log(data);
this.contact = data;
}.bind(this));
}
3- (recommended with ES6) you can use an arrow function (arrow functions do not have their own context, so they preserve the one where they are created)
activate(id) {
this.id = id;
return dpd.contacts.get(id).then((data) => {
console.log(data);
this.contact = data;
});
}
Andrew Grothe
Andrew Grothe is an IT Consultant specializing in programming & data during the day. At home he is a father, husband, hobbyist musician and open net-worker.
Updated on June 13, 2022Comments
-
Andrew Grothe over 1 year
Not sure what I'm missing here.
I need to get the output of
data
intothis.contact
. Right now, I'm using a static class variable, but it seems dirty to have to do that.export class contactEdit { static t; // static class var constructor() { this.id = null; this.contact = null; contactEdit.t = this; } activate(id) { this.id = id; let contact = this.contact; // scoped version of class var return dpd.contacts.get(id).then(function(data) { console.log(data); contactEdit.t.contact = data; // this works contact = data; // this doesn't }); } }
Normally I would create a
var contact
inside theactivate()
function (it works in the Chrome console) but this doesn't seem to working in ES6.Chrome console:
var c = null; undefined c; null dpd.contacts.get('a415fdc8f5a7184d').then(function(data) { c = data; }); Object {}fail: (n)then: (e,t)__proto__: Object c; Object {firstName: "John", lastName: "Doe", id: "a415fdc8f5a7184d"}
-
Matthew James Davis over 7 yearsbest answer on all of stack overflow today
-
Andrew Grothe over 7 years@MatthewJamesDavis I Agree, the arrow function does the trick.
-
Andrew Grothe over 7 years@AshleyGrant, perhaps you could add a sentence or two on why the arrow function fixes this? I'm going to go read up on this but would help others I'm sure.
-
Andrew Grothe over 7 yearsI had already tried #1 with no luck. Going to try #2 though to see how that works. #3 works.
-
Andrew Grothe over 7 years#1 and #2 also work. My error was using
let contact = this.contact
. Apparently that won't work where aslet that = this
does work. Odd, but I'll take it. -
Andrew Grothe over 7 yearsFor others interested in the details, see the Lexical This section from here: developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
-
Quentin Roy over 7 yearsThis is not odd. If you do
contact = something
, you are assigning a new value to thecontact
variable. You are not modifying the previous value that were assigned to it. What you are trying to do is to change thecontact
property of thethis
object. This property is unrelated to thecontact
variable (apart from the fact that you initialise its value to the value pointed bythis.contact
). The only way to change the value pointed by the propertyprop
of an objectobj
is by writing something similar toobj.prop = something
.