Web Develop Wolf
Web Develop Wolf

Reputation: 6316

Data returned as undefined in ngOnInit() but not in function

I'm returning data from an API and I've put in several console.log() statements for debugging. In the ngOnInit(), the console.log is printing undefined, but in the separate function the console.log returns the correct data and in theory, no other processing is done in between.

ngOnInit() {
    this.loadAnimalList('fur');
    console.log(this.animalsFur);
  }

  loadAnimalList(classification: string) {
    this.animalService.getAnimals(classification).subscribe((animals: Animal[]) => {
      switch (classification) {
        case 'fur':
          this.animalsFur = animals;
          break;
        case 'feather':
          this.animalsFeather = animals;
          break;
        case 'scales':
          this.animalsScales = animals;
          break;
        case 'other':
          this.animalsOther = animals;
          break;
        default:
          this.animalsFur = animals;
          break;
      }
    }, error => {
      this.alertify.error(error, 'Failed to Load Animals...');
    });
  }

The console.log I've left in id the one that returns undefined, if I put one (for example) after the switch is complete, or in case statement then the correct data is shown in the console, just not in the onInit

Upvotes: 1

Views: 650

Answers (1)

wentjun
wentjun

Reputation: 42516

That's because getAnimals is asynchronous. That's why console.log(this.animalsFur); returns undefined, as getAnimals has not finished running when the console statement is called. You should read up more about JavaScript's event loops, if you want to gain more context about it.

On the other hand, calling the console statement within subscribe will ensure that the animalsFur property is assigned with the value from the response, as the block of code within subscribe will only run after the observable from getAnimals() is returned.

this.animalService.getAnimals(classification).subscribe((animals: Animal[]) => {
  switch (classification) {
    case 'fur':
      this.animalsFur = animals;
      break;
    case 'feather':
      this.animalsFeather = animals;
      break;
    case 'scales':
      this.animalsScales = animals;
      break;
    case 'other':
      this.animalsOther = animals;
      break;
    default:
      this.animalsFur = animals;
      break;
  }
  // the below should be defined
  console.log(animals);
  // this should be defined as long classification === 'fur', or if the switch statement hits default case
  console.log(this.animalsFur);
}, error => {
  this.alertify.error(error, 'Failed to Load Animals...');
});

Upvotes: 2

Related Questions