1

I need to use Promise to execute things order in the following code. My actual save is ajax POST and want to call execute only after that successful POST. Everything is working fine, but the problem is that I can't access the actual this variable, inside execute function. console.log(this.abc); gives me undefined why?.

  function MyClass(context) {
      this.abc  = "xyz";
  };

  MyClass.prototype.save = function() {
    console.log(" saving");
    return new Promise(function(resolve, reject){
      resolve();
    });
  };

  MyClass.prototype.execute = function() {
    console.log(" executing");
    console.log(this.abc);
  };

  var myInstance = new MyClass();

  window.addEventListener('keydown', function(e) {
    e.preventDefault();
    if(event.ctrlKey & (event.which==83)) {
      myInstance.save();
    } else if (event.ctrlKey && (event.which==69)) {
      myInstance.save().then(myInstance.execute);
    }
  }, false);
Jayendra Parmar
  • 702
  • 12
  • 30

1 Answers1

1

Because you are passing a reference to a function to be executed by some other code, without specifying what to use as this.

Instead of

myInstance.save().then(myInstance.execute);

You can do

myInstance.save().then(function() { myInstance.execute() });

Because in that case you are the one calling execute using dot notation, which means that the object to the left of the dot will be used as this (myInstance).

You can also use Function.bind

myInstance.save().then( myInstance.execute.bind(myInstance) });

The lesson is, what matters is how the function gets called, it could be:

var a = {
  prop: 1,
  b: function() {
      console.log(this.prop);
  }
};

Dot notation

// `this` will be `a`, logs 1
a.b(); 

Loose function call

// If in strict mode, `this` will be undefined, and it will throw an error
// otherwise `this` will be the global object and it will log undefined
var b = a.b;
b();

Using apply or call

var b = a.b;
// Call b passing a as `this` and 2 as its argument which is ignored
// Logs 1
b.call(a, 2);

Bind this yourself

var b = a.b.bind(a);
// b has been bound to a, it will correctly output 1
b();
// Even if you try to use another this
b.call({prop: 2}); // Still logs 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217