dros
dros

Reputation: 1567

Type 'Object' is not assignable to type 'NgIterable<any> | null | undefined'. in Angular 11

learning angular and typescript for the first time and cannot understand why this is not valid!

http.service.ts

export class HttpService {


  constructor(private http: HttpClient) { }

  getBeer() {
    return this.http.get('https://api.openbrewerydb.org/breweries')
  }
}

that api returns an object

the component its being used in: 


export class ListComponent implements OnInit {

  brews: Object;

  constructor(private _http: HttpService) { }

  ngOnInit() {
    this._http.getBeer().subscribe(data => {
      this.brews = data
      console.log(this.brews);
    }
  )
  }

}

im getting an error in the line

brews: Object;

which says:

error TS2322: Type 'Object' is not assignable to type 'NgIterable | null | undefined'. The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead?

i've tried:

brews: any;

and

brews: Object[] = [];

but nothing seems to work.

can someone explain where I am going wrong?

that api returns an object, so why cant I do

brews: Object; 

the template its being used for:

<h1>Breweries</h1>

<ul *ngIf="brews">
  <li *ngFor="let brew of brews">
    <p class="name">{{ brew.name }}</p>
    <p class="country">{{ brew.country }}</p>
    <a class="site" href="{{ brew.website_url }}">site</a>
  </li>
</ul>

Upvotes: 4

Views: 10924

Answers (2)

Alireza Ahmadi
Alireza Ahmadi

Reputation: 9923

It is good idea create a custom type based on your data. But if you insist on using anonymous type you may need to use any[] type to solve the problem:

brews: any[];

And you can use generic methods in http client like get<your_type[]>:

this._http.get<any[]>('https://api.openbrewerydb.org/breweries').subscribe(data => {
      this.brews = data 
      console.log(this.brews);
    })

OR something like this:

this._http.get('https://api.openbrewerydb.org/breweries').subscribe(data => {
          this.brews = data as any[]
          console.log(this.brews);
    })

Here is working sample: StackBlitz

Upvotes: 2

chris burd
chris burd

Reputation: 818

it's a bad idea to name your service in the restricted name space. httpservice is not a good name to use and could lead to some weird problem later.

you should use a behavior subject which allows you to share the object as an observable from all components.

service

export class BeerService {
    private beer = new BehaviorSubject<any>({});
        public beer$ = this.beer.asObservable();
      
        getBeer(){
          this.http.get('https://api.openbrewerydb.org/breweries').pipe(map((res) => (res = res))).subscribe((sub) => {
            sub = sub;
            // set beer object next
            this.beer.next(sub)
            // , take(2)
             })
        }
      

on your component

  constructor(beer:BeerService) {}
  ngOnInit(){
       this.beer.beer$.subscribe((beer)=>{ 
      this.beer = beer})
  }

you can read about behavior subjects here. https://www.learnrxjs.io/learn-rxjs/subjects/behaviorsubject

Upvotes: 0

Related Questions