Prozak
Prozak

Reputation: 303

Making an API GET request and displaying the information in HTML.

I have been attempting to make an API call but have had no success. I get this error message when displaying the name. Very sorry that I've pasted in three files but this is my first question here and I'm a newbie. Thanks for any help.

Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.

Here is my beers.service.ts file

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class BeersService {
  private beerUrl = 'https://api.punkapi.com/v2/beers/';
  beers;

  constructor(private _httpClient: HttpClient) { }

  getListOfBeer() {
    return this._httpClient.get(this.beerUrl).subscribe(
      res => {
         this.beers = res;
    });
  }
}

Here is my app.component.ts I have a feeling the problem is with the constructor but everything I have tried has led to no success.

import { Component } from '@angular/core';
import { BeersService } from './beers.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  beers;

  constructor(private _beerService: BeersService) {
    this.beers = _beerService.getListOfBeer()
  }
}

And finally here is my app.component.html

<div class="container">
  <div *ngFor="let beer of beers">
    <p>{{ beer.name }}</p>
  </div>
</div>

Upvotes: 2

Views: 53

Answers (2)

Zlatko
Zlatko

Reputation: 19578

You have an uninitialized variable. When you just say beers or beers:any, it is still undefined. Which means, your template is trying to loop something that is undefined (until the API request comes back, which is a few miliseconds after you get the thing).

Preinitialize the array or show it conditionally.

Version 1:

Preinitialize the array in app.component.ts:

export class AppComponent {
  beers = [];
  ...

Version 2

On app start, your component.beers is undefined, until the API returns. You can not loop undefined, so hide the list until then. Check out beers.component.html:

<div class="container" *ngIf="beers">
    <div *ngFor="let beer of beers"><p>{{ beer.name }}</p>
</div>

Upvotes: 0

You should read about RxJS as it is used in Angular HTTP client. Function getListOfBeers returns a Subscription, not an array of beers.

In Service

getListOfBeer() {
    return this._httpClient.get(this.beerUrl);
}

In Component

constructor(private _beerService: BeersService) {
    _beerService.getListOfBeer().subscribe(res => this.beers = res)
}

and make sure that you instantiate beers with an empty array

beers = []

Upvotes: 3

Related Questions