57

I want to be able to call a function inside the .then scope, and for that I use the this.foo() manner. But if I do this inside the .then I get an error, since this appears to be lost. What can I do?

In this code, this would be equivalent to have the same output for the object this

console.log(this)
one().then(function() {
  console.log(this)
})

function one() {
  var deferred = $q.defer();
  deferred.resolve()
  return deferred.promise;
}

This neither seems to work

console.log(this)
var a = this;
one().then(function(a) {
  console.log(a)
})
GWorking
  • 4,011
  • 10
  • 49
  • 90
  • 2
    If you remove the `a` argument from `one().then(function(a) {` so that it's `one().then(function() {`, then that will give you the result you want. – Andy Sep 13 '15 at 08:24
  • Yes, I was testing it just when I've seen your answer. You're totally right! I'll mark it as an answer if you post it as an answer – GWorking Sep 13 '15 at 08:26

1 Answers1

66

Your second code example is the right way to go. Because the scope changes in the new function, this changes too, so you're right to make a reference to this outside of the function.

The reason it failed is because the function is using a that you passed into the function rather than the global a you defined outside it.

In other words:

var a = this;

one().then(function () {
  console.log(a)
});

Update: use an arrow function - they borrow the context (this) from their outer scope.

function two() {
  console.log('Done');
}

one().then(() => {
  this.two();
});

function one() {
  return new Promise(res => {
    setTimeout(() => res(), 2000);
  });
}
Andy
  • 61,948
  • 13
  • 68
  • 95
  • 44
    or ... `one().then(function () { console.log(this) }.bind(this))` _usual disclaimer that internet exploder before 9 is a waste of disk space and should never be relied on to do anything other than display static web pages_ – Jaromanda X Sep 13 '15 at 08:50
  • 2
    Yeah, @JaromandaX, I was just looking over the edit someone made to the answer and the code didn't look right. Yours looks accurate. – Andy Sep 13 '15 at 08:54
  • 2
    yours is right, and probably easier to use in many cases, you know just by looking where you put `var a = this` exactly what `a/this` will be - whereas, using bind, it may not be exactly what you expect or want for that matter :p – Jaromanda X Sep 13 '15 at 08:56
  • Thanks a lot for your great example. – Fernando Jaconete Jul 23 '19 at 01:59