1

I am using the new window.Fetch method to fetch some JSON. This returns a promise object, from which I can read the json data with console.log.

But if I use the fetch method inside an angular component, I am unable to call other methods when the result is returned. It seems that the scope is somehow lost?

See the comments below:

(function(app) {

  app.Actorlist =
    ng.core.Component({
      selector: 'actor-list',
      templateUrl: './app/actorlist.component.html'
    })
    .Class({
      constructor: function() {
      },

      showActors: function(js) {
          this.actorName = js.name;
      },

      searchActor: function(){

        fetch('http://swapi.co/api/people/1/')
          .then(function(response) {
            return response.json();
          })
          .then(function(js) {
            // this logs the json result correctly
            console.log(js);

            // error: showActors is not defined
            showActors(js);

            // error: this.showActors is not defined
            this.showActors(js);

            // should I use return? return to where?
            return js;
          });
      }
    });

})(window.app || (window.app = {}));
a better oliver
  • 26,330
  • 2
  • 58
  • 66
Kokodoko
  • 26,167
  • 33
  • 120
  • 197
  • 1
    [`.bind()`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind) your callbacks to `this`. – Yaroslav Admin Nov 25 '16 at 13:12
  • If I use "this.showActors(js).bind(this);" I get the same error "this.showActors is not a function". I also thought that .bind is no longer needed in ES6... – Kokodoko Nov 25 '16 at 13:15
  • 1
    It should be `.then(function() {...}.bind(this))` but better to use arrow function. – dfsq Nov 25 '16 at 13:16
  • @Kokodoko `bind(this)` is not needed in ES6 _arrow functions_ `() => { }` – Robin-Hoodie Nov 25 '16 at 13:16
  • 1
    It's not needed if you use arrow functions as suggested in the answer below. Since arrow functions don't have their own `this` context. You should bind not the method, you're calling, but callback. Something like this: `.then((function(js) { ... }).bind(this));`. – Yaroslav Admin Nov 25 '16 at 13:17

1 Answers1

2

Use arrow functions to preserve lexical context:

fetch('http://swapi.co/api/people/1/')
  .then(function(response) {
    return response.json();
  })
  .then(js => {
    this.showActors(js);
  });

You also don't really need to return anything from promise callback as you don't use this promise chain further any way.

dfsq
  • 191,768
  • 25
  • 236
  • 258