Reputation: 4712
I am working on a Contacts app with Angular 9. I get a list of contacts via the following service:
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Contact } from '../models/Contact';
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json'
})
}
@Injectable({
providedIn: 'root'
})
export class ContactsListService {
contactsUrl = 'https://randomuser.me/api/?&results=500&inc=name,location,email,cell,picture';
constructor(private http:HttpClient) { }
getContcts():Observable<Contact[]> {
return this.http.get<Contact[]>(`${this.contactsUrl}`);
}
}
The Contacts List component is as follows:
import { Component, OnInit } from '@angular/core';
import { from } from 'rxjs';
import { ContactsListService } from '../../services/contacts-list.service';
import { Contact } from '../../models/Contact';
@Component({
selector: 'app-list',
templateUrl: './list.component.html',
})
export class ListComponent implements OnInit {
contactsList:Contact[];
constructor(private ContactsListService:ContactsListService) { }
ngOnInit(): void {
this.ContactsListService.getContcts().subscribe(contactsList => {
this.contactsList = contactsList;
});
}
}
Trying to iterate the contacts list this way
<ul *ngFor="let contact of contactsList">
<li>{{contact.name.first}}</li>
</ul>
throws the error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays
.
That very likely means contactsList
is not an array.
What am I doing wrong?
Upvotes: 0
Views: 1114
Reputation: 31135
The URL is returning an object of the form
{
results: [],
info: {}
}
Use RxJS map
to map the results
obtained from the API.
Service
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { pipe } from 'rxjs';
import { map } from 'rxjs/operators';
import { Contact } from '../models/Contact';
export class ContactsListService {
contactsUrl = 'https://randomuser.me/api/?&results=500&inc=name,location,email,cell,picture';
constructor(private http:HttpClient) { }
getContcts():Observable<Contact[]> {
return this.http.get<Contact[]>(`${this.contactsUrl}`)
.pipe(map(response => response['results']));
}
}
Assign empty array to contactsList
on declaration.
Component
import { Component, OnInit } from '@angular/core';
import { from } from 'rxjs';
import { ContactsListService } from '../../services/contacts-list.service';
import { Contact } from '../../models/Contact';
@Component({
selector: 'app-list',
templateUrl: './list.component.html',
})
export class ListComponent implements OnInit {
contactsList: Contact[] = []; // assign empty array
constructor(private ContactsListService:ContactsListService) { }
ngOnInit(): void {
this.ContactsListService.getContcts().subscribe(
contactsList => { this.contactsList = contactsList; },
error => { // always good practice to handle error when subscribing to HTTP observables }
);
}
}
Upvotes: 3
Reputation: 4993
Seems like the endpoint 'https://randomuser.me/api/?&results=500&inc=name,location,email,cell,picture' does not return an array. To check it you may open it in the browser, or check in the network tab of the chrome developers tools while your app running
Upvotes: 0