2

I'm following the quickstart tutorial for Angular 2 (https://angular.io/docs/ts/latest/tutorial/toh-pt4.html#!#review-the-app-structure) and I got stuck in the Services chapter. This is my component:

@Component({
  selector: 'main',
  templateUrl: 'main/main.template.html',
  styleUrls: ['main/main.component.css'],

  providers: [HeroService],
  directives: [HeroComponent]
})

export class MainComponent implements OnInit {
  title: String = 'Tour of heroes';
  heroes: Hero[];
  selectedHero: Hero;

  constructor(private _heroService: HeroService) {

  }

  getHeroes() {
    this._heroService.getHeroes().then(heroes =>
      this.heroes = heroes
    );
  }

  ngOnInit() {
    this.getHeroes();
  }

  onSelect(hero: Hero) { this.selectedHero = hero; }
}

As you can see it implements OnInit, which executes the component's getHeroes method, which in turns calls the injected HeroService:

import { Injectable } from 'angular2/core';
import { HEROES } from '../hero/hero.mock';

@Injectable()
export class HeroService {
  public getHeroes() {
    return Promise.resolve(HEROES);
  }

}

The promise resolves successfully and I get the array from hero.mock.ts in the response variable:

getHeroes() {
  this._heroService.getHeroes().then(heroes =>  // heroes = Array[10]
    this.heroes = heroes
  );
}

The problem I'm facing is the first this (this._heroService) is correctly set to MainComponent, but the second one (this.heroes) is referencing the Window javascript object. I've checked several other answers, including this and done as they suggest, but the problem remains. Can anyone think of a reason why this is happening?

Edit: Generated javascript for MainComponent#getHeroes

MainComponent.prototype.getHeroes = function () {
    var _this = this;
    this._heroService.getHeroes().then(function (heroes) {
        return _this.heroes = heroes;
     });
};
MainComponent.prototype.ngOnInit = function () {
    this.getHeroes();
};

Another edit: If I change the method calling the service to this (note the curly brackets wrapping everything after the =>) then this is MainComponent, but neither the changes in the title nor in the heroes array are reflected in the view:

getHeroes() {
  this._heroService.getHeroes().then(heroes => {
    console.log(this);
    this.title = 'modified string';
    this.heroes = heroes;
  });
}
Community
  • 1
  • 1
Carlos Romero
  • 698
  • 8
  • 18
  • What about making a reproducible Plunker by using the Plunker provided in the tutorial and modify it so it demonstrates your issue? (https://angular.io/resources/live-examples/toh-4/ts/plnkr.html) – Günter Zöchbauer Mar 07 '16 at 07:00
  • How exactly did you figure out that 'this' is 'window'? It is highly unlikely that `this._heroService.getHeroes().then(heroes => this.heroes = heroes)` will result in different `this` contexts, just because it can't do that with an arrow. – Estus Flask Mar 07 '16 at 07:37
  • Could you provide the compiled ES5 code for this TypeScript class? Thanks! – Thierry Templier Mar 07 '16 at 08:00
  • @estus I just breakpointed it in the chrome devtools and checked the content. – Carlos Romero Mar 07 '16 at 08:14
  • @Thierry sure! I'll do that in the afternoon. – Carlos Romero Mar 07 '16 at 08:14
  • @Günter I'll get the plunker done later on, thanks! – Carlos Romero Mar 07 '16 at 08:15
  • I created a plunkr for your problem: https://plnkr.co/edit/6cja0ICCVjaKRINoRBA0?p=preview. But I can't reproduce it... – Thierry Templier Mar 07 '16 at 10:49
  • @Thierry I'm creating the plunkr. In the meantime, I pushed to github https://github.com/gatperdut/heroes – Carlos Romero Mar 07 '16 at 16:20
  • I added the relevant generated js too. – Carlos Romero Mar 07 '16 at 16:27
  • I've tested your code but I got no exception... – hzitoun Mar 07 '16 at 16:44
  • hey @Hamed no exception is happening, it just fails to render anything. there's an addendum to my question involving curly brackets `{ }` which actually make `this` have the correct value. still, nothing is rendered. – Carlos Romero Mar 07 '16 at 16:49
  • @Thierry so I managed to make `this` be `MainComponent`, but the changes (updating the `heroes` attribute) don't seem to be reflected. Where are you defining `Hero` in your plnkr, by the way? – Carlos Romero Mar 07 '16 at 18:39
  • What was your problem? To make your changes reflected, you need to have instantiate your `heroes` array within Angular2. I mean in the constructor of a service or a component... – Thierry Templier Mar 07 '16 at 18:44
  • yep, the array is instantiated as `heroes: Hero[];` in the component like in the question and the github repo. Thank you anyway, I'll keep hacking at it. – Carlos Romero Mar 07 '16 at 18:53
  • @CarlosRomero you really should create a plunkr for your code because it seems like many are having problems understanding your issues ... – hzitoun Mar 08 '16 at 09:14
  • I posted somewhere above the github repo. At any rate, I fixed it -- it seemed to be a problem with library versions, since all I changed was the `` for example) and...voilà, working as expected. So I kind had it right from the beginning grr – Carlos Romero Mar 08 '16 at 20:06

0 Answers0