Search code examples
arraysangularrxjs-observables

showing by console.log an observable array in angular 8


I am trying to show response from an observable on console that comes from a service in my angular project. But it appears to be undefined. When I try with a loop, the error in console says it is not iterable while the observable is supposed to return an array. Why could this be happening?

Component

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

  heroes: Hero[];          

  constructor(private heroService: HeroService, private messageService: MessageService) { }

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


  ngOnInit() {
    this.getHeroes();
    // for(let hero of this.heroes){
    //   console.log(hero);
    // }
    console.log(this.heroes);
  }

}

Service

@Injectable({
  providedIn: 'root'
})
export class HeroService {

  private heroesUrl = 'api/heroes';  

  constructor(
    private messageService: MessageService,
    private http: HttpClient
  ) { }

  httpOptions = {
    headers: new HttpHeaders({ 'Content-Type': 'application/json' })
  };

  getHeroes(): Observable<Hero[]> {
    return this.http.get<Hero[]>(this.heroesUrl)
    .pipe(
      tap(_ => this.log('fetched heroes')),
      catchError(this.handleError<Hero[]>('getHeroes', []))
    );
  }


  private log(message: string) {
    this.messageService.add(`HeroService: ${message}`);
  }

  private handleError<T>(operation = 'operation', result?: T) {
    return (error: any): Observable<T> => {

      console.error(error); 

      this.log(`${operation} failed: ${error.message}`);

      return of(result as T);
    };
  }

}

Solution

  • That is happening because the request is asynchronous, that means the execution of the program continues while the request is resolved.

    In other you should use the result of the request when it is resolved. In your example that would be after you are assigning the returned value of the request to heroes property.

    getHeroes(): void {
      this.heroService.getHeroes()
        .subscribe(data => {
          this.heroes = data; // <- after this point you have the result 
          console.log(this.heroes);
      });     
    }