0
votes

So not much is said about this particular line of code inside of the tutorial itself:

getHeroes(): void {
  this.heroService.getHeroes()
      .subscribe(heroes => this.heroes = heroes) ;

}

From what I have seen, .subscribe retrieves "HEROES" from the hero.service method and passes it into the heroes parameter inside of the .subscribe method.

This is at least what I think is happening. Some peculiarities, if I console.log like this:

getHeroes(): void {
  this.heroService.getHeroes()
      .subscribe(heroes => console.log(this.heroes )) ;

}

I get an undefined for "this.heroes"

however, if I console.log like this:

.subscribe(heroes => console.log(this.heroes = heroes))

I get an output of the array that it is calling:

(10) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
0: {id: 11, name: "Dr Nice"}
1: {id: 12, name: "Narco"}
2: {id: 13, name: "Bombasto"}
3: {id: 14, name: "Celeritas"}
4: {id: 15, name: "Magneta"}
5: {id: 16, name: "RubberMan"}
6: {id: 17, name: "Dynama"}
7: {id: 18, name: "Dr IQ"}
8: {id: 19, name: "Magma"}
9: {id: 20, name: "Tornado"}

Even more peculiar, if I console.log this.heroes outside of the .subscribe method, I get a list of the heroes as a well, like so:

getHeroes(): void {
  this.heroService.getHeroes()
      .subscribe(heroes => this.heroes = heroes),
      console.log(this.heroes) ;

}

which outputs:

(10) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
0: {id: 11, name: "Dr Nice"}
1: {id: 12, name: "Narco"}
2: {id: 13, name: "Bombasto"}
3: {id: 14, name: "Celeritas"}
4: {id: 15, name: "Magneta"}
5: {id: 16, name: "RubberMan"}
6: {id: 17, name: "Dynama"}
7: {id: 18, name: "Dr IQ"}
8: {id: 19, name: "Magma"}
9: {id: 20, name: "Tornado"}

So my question is, what is happening to heroes inside of the subscribe method? Is it returning the list from the service and then passing it to the heroes parameter inside of the subscribe method?

For further reference to where I am at on the tutorial: https://angular.io/tutorial/toh-pt4#subscribe-in-heroescomponent

One more thing to add, I thought that "heroes" was being set to the heroes:Hero[] array in the code, but it is not:

import { Component, OnInit } from '@angular/core';
import { Hero } from './hero';
import { HeroService } from '../hero.service';

@Component({
  selector: 'app-heroes',
  templateUrl: './heroes.component.html',
  styleUrls: ['./heroes.component.css']
})
export class HeroesComponent implements OnInit {

  heroes: Hero[];

selectedHero: Hero;

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

getHeroes(): void {
  this.heroService.getHeroes()
      .subscribe(heroes => this.heroes = heroes),
      console.log(this.heroes) ;

}




  constructor(private heroService : HeroService) {



   }

  ngOnInit() { 
    this.getHeroes();
  }

}

If I delete

heroes: Hero[];

from inside of the heroes.component, I still get a list of heroes to display. So this.heroes is not binding to heroes: Hero[]

live example: https://stackblitz.com/angular/aaldojlqqlvd?file=src%2Fapp%2Fheroes%2Fheroes.component.ts

1

1 Answers

3
votes

It's important to view the whole heroes.component.ts as you can see there is an array called heroes defined at the top. So what the function is doing is setting the heroes array defined in the component to the heroes array that is returned by the service. With new names it could be like this:

    import { Component, OnInit } from '@angular/core';

    import { Hero } from '../hero';
    import { HeroService } from '../hero.service';

    @Component({
      selector: 'app-heroes',
      templateUrl: './heroes.component.html',
      styleUrls: ['./heroes.component.css']
    })
    export class HeroesComponent implements OnInit {

      selectedHero: Hero;

      heroesInComponent: Hero[]; // <<<< changed

      constructor(private heroService: HeroService) { }

      ngOnInit() {
        this.getHeroes();
      }

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

      getHeroes(): void {
        this.heroService.getHeroes()
            .subscribe(heroesFromService=> this.heroesInComponent = heroesFromService); // <<<< changed
      }
    }

The reason why your snippet logs undefined is because heroesInComponent is still undefined because you haven't assigned a value to it (e.g. heroesFromService)

getHeroes(): void {
  this.heroService.getHeroes()
      .subscribe(heroes => console.log(this.heroesInComponent)) ;
}

The reason why this snippet logs the correct result is because the = (assignment) operator returns the resulting array after assigning.

.subscribe(heroes => console.log(this.heroesInComponent = heroesFromService))