0

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?

3
  • Please check the response you are getting from your API. It returns an object with "info" and "results" as keys. Commented May 2, 2020 at 19:17
  • console.log(typeof this.contactsList); returns an object. Commented May 2, 2020 at 19:21
  • typeof would anyway return an Object for both an Array or an Object, you would need to log, this.contactList to see the actual content Commented May 2, 2020 at 19:22

2 Answers 2

3

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 }
    );
  }
}
Sign up to request clarification or add additional context in comments.

3 Comments

I get the error: error TS2552: Cannot find name 'map'. Did you mean 'Map'?.
I overlooked you had a service. I've updated the whole answer. Please see if it works for you.
You need to import map. Notice the new import statements at the beginning of the service file.
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.