1

I have a js object, and I have a method that calls another method and gets returned a promise, but from within .then() I cannot access a member function foo(). Why can't I access foo() and how can I access it? Here is my code:

function LoadImageGroupFormat() {
    return new Promise(function(resolve, reject) {
      var xhttp = new XMLHttpRequest();
      xhttp.open('GET', "imagegroup_format.txt");
      xhttp.onload = function() {
        if (xhttp.status == 200) resolve(xhttp.responseText);
        else reject(Error(xhttp.statusText));
      };
      xhttp.onerror = function() {
        reject(Error("Network Error"));
      };
      xhttp.send();
    });
  }
  //the object
var Registerhandler = {
  imageGroupIndex: 0,

  foo: function() {
    //Do something else here
  },

  GetImageGroupFormat: function() {
    var imageGroupIndex = this.imageGroupIndex;
    LoadImageGroupFormat().then(function(ImageGroup_Format) {
      //Do something with ImageGroup_Format
      imageGroupIndex++; //This works
      foo(); //Doesn't work - undefined
    }, function(error) {
      console.error("Failed to Load ImageGroup Format", error);
    });
  }
}

Thanks for any help on this.

James A
  • 467
  • 4
  • 12

2 Answers2

1

foo is a property, not a function/variable name, you need to call it using property syntax. And since this isn't saved in closures, you need to define a local closure variable to hold it.

You also need to use self.imageGroupIndex to update that property, otherwise you're incrementing a copy of the value.

var Registerhandler = {
  imageGroupIndex: 0,

  foo: function() {
    //Do something else here
  },

  GetImageGroupFormat: function() {
    var self = this;
    LoadImageGroupFormat().then(function(ImageGroup_Format) {
      //Do something with ImageGroup_Format
      self.imageGroupIndex++;
      self.foo();
    }, function(error) {
      console.error("Failed to Load ImageGroup Format", error);
    });
  }
}
Barmar
  • 741,623
  • 53
  • 500
  • 612
1

Use Function.prototype.bind(), The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

function LoadImageGroupFormat() {
  return new Promise(function(resolve, reject) {
    resolve('success!'); //updated fro demonstration purpose
  });
}
var Registerhandler = {
  imageGroupIndex: 0,
  foo: function() {
    alert('In foo!');
  },

  GetImageGroupFormat: function() {
    var imageGroupIndex = this.imageGroupIndex;
    LoadImageGroupFormat().then(function(ImageGroup_Format) {
      console.log(ImageGroup_Format);
      this.imageGroupIndex++;
      this.foo();
    }.bind(this), function(error) {
      console.error("Failed to Load ImageGroup Format", error);
    });
  }
}
Registerhandler.GetImageGroupFormat();
Rayon
  • 36,219
  • 4
  • 49
  • 76
  • I don't think that will work. At the time you call `.bind`, you're not in a method of the object, so `this` is not set to the object. – Barmar May 23 '16 at 15:31
  • @Barmar, I have provided a demo..Let me know it it fails.. – Rayon May 23 '16 at 15:35
  • @Barmar Yes you are. `bind` is directly called in the `GetImageGroupFormat` method. – Quentin Roy May 23 '16 at 15:35
  • Sorry, I misread, I thought you were calling `.bind()` on the `GetImageGroupFormat` function, not the `.then()` function inside it. – Barmar May 23 '16 at 15:37
  • @Barmar, In my initial answer, I did that way only.. Thanks for correction :) – Rayon May 23 '16 at 15:39