What is the best way to display data retrieved through an HTTP service using ngFor?

I was attempting to inject a service (contact.service.ts) into a component (contact-list.component). The service contains data on employees defined in contacts.ts. While I was able to successfully receive the data, I encountered difficulty in rendering it using ngFor.

---------contacts.ts---------------


export interface Contacts {
  contactsList: Contact[];
}
export interface Contact {
  id: number;
  name: string;
  city: string;
}

------------contact.service.ts-----------


import { HttpClient } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { Contacts } from '../models/contacts';

export class ContactService {
  url = 'http://www.mocky.io/v2/5c5d880f3200000e11220880';

  constructor(private http: HttpClient) { }

  getContacts(): Observable<Contacts> {
    return this.http.get<Contacts>(this.url);
  }
}

-----------contact-list.component--------------


import { ContactService } from 'src/app/services/contact.service';
import { Contacts } from 'src/app/models/contacts';

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

  contacts;

  constructor(private _contactService: ContactService) { }

  ngOnInit() {
      this._contactService.getContacts().subscribe(data => this.contacts=data);
  }
}

Here is my attempt at rendering the data:


<p class="title"> Contact Applications </p>
<div class="list">
  <p *ngFor="let contact of contacts">
    {{contact.name}}
  </p>
</div>

However, I encountered this error message:


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

Answer №1

Observe the information retrieved from the API: it's not structured as an array, but rather as an object that includes an array. As a result, you need to

this._contactService.getContacts()
    .subscribe(response => this.contacts = response.contactsList);

Answer №2

As shown below:

<div *ngFor="let contact of contacts; let i = index;">
     {{contact.[field_name]}}
</div>

However, it is important to validate the data. Kindly include console.log(this.contacts) and display the output

Answer №3

Your component is attempting to access a variable named "contacts" without specifying its type. To properly access the properties of this variable in your template, you should declare it as type "Contacts" within your ContactListComponent class like so:

export class ContactListComponent implements OnInit {
  contacts: Contacts; // By declaring contacts as type Contacts, you can access its properties

Answer №4

Declare the following in your ContactListComponent:

contacts: Contacts;

Then, in your page:

<p *ngFor="let contact of contacts.contactsList">
    {{contact.name}}
</p>

Feel free to refactor the code to utilize Contact[] instead of the Contacts interface if you prefer.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the most efficient way to perform an inline property check and return a boolean value

Can someone help me with optimizing my TypeScript code for a function I have? function test(obj?: { someProperty: string}) { return obj && obj.someProperty; } Although WebStorm indicates that the return value should be a boolean, the TypeScript compil ...

How can a new component be added as a child of an element without replacing or interfering with other

Whenever I dynamically generate components and attach them as children to an element upon creation, everything within that element gets deleted. Here's an example: public fn(event) { // Create component factory const factory = this.componentF ...

How to dynamically add a route from an HTTP API to the app-routing.module.ts file in Angular 10

Struggling with an issue while working on Angular 10 version. Despite finding numerous solutions for older versions of Angular, I am still unable to resolve the issue. I consider myself a beginner in Angular as I try to create a website using an Angular c ...

having difficulty disabling a form field in angular 14's reactive forms

For my users, I am attempting to set specific form fields as read-only using reactive forms in Angular 14. My goal is to bind a value to the field without allowing the user to interact with it. Despite trying to disable the control after setting the value ...

The Angular Compiler was identified, however it turned out to be an incorrect class instance

Although this question has been asked before, I have exhausted all possible solutions that were suggested. Unfortunately, I still cannot resolve it on my own. Any assistance would be greatly appreciated. Error: ERROR in ./src/main.ts Module build failed: ...

Using string replacement for effective search finding: Unleashing the power of substring matching

I have a method that adds an anchor tag for each instance of @something. The anchor tag links to a specific sub URL. Check out the code: private createAnchors(text: string) { return text.replace(/(@[^ @]+)/ig, '<a href="/home/user/$1">$1& ...

I'm curious, which redux architecture would you recommend for this specific scenario?

I'm currently developing an application and I'm facing a challenge in implementing Redux effectively in this particular scenario. Unfortunately, due to restrictions at my workplace, normalizing data is not an option. Let's consider the foll ...

I'm struggling to understand how to use rxjs 6 in conjunction with angular 6, specifically when it comes to utilizing interval

I'm struggling to update my rxjs code to version 6. Previously, I had the following code that would poll for new data every 5 seconds: import { Observable, interval } from 'rxjs'; import { switchMap, map } from 'rxjs/operators'; ...

Tips for integrating Reactjs with Chessboard.js

Recently, I stumbled upon chessboardjs (https://chessboardjs.com/) as a way to hone my React coding skills. However, I hit a roadblock while trying to implement a simple example of displaying the chess board in my application. The documentation instructed ...

How to apply conditional styling to text using Angular2

I need to display a list of objects that contain names and numbers. The color of the name should change based on the number associated with it - red for 1, blue for 2, green for 3, and orange for 4. My template currently looks like this: <p *ngFor="l ...

Tips on how to retrieve an Observable Array instead of a subscription?

Is there a way to modify this forkJoin function so that it returns an observable array instead of a subscription? connect(): Observable<any[]> { this.userId = this.authService.userId; this.habits$ = this.habitService.fetchAllById(this.userId); this.s ...

Mongoose TypeScript Aggregation error: is not a valid property of type 'any[]'

Attempting to replace a standard mongo call with an aggregate call. The original code that was functional is as follows: const account = await userModel .findOne({ 'shared.username': username }) .exec(); console.log(account._id) The n ...

Provide a string argument when instantiating an abstract class

I am searching for a method to assign a name string within a class and utilize it in the abstract class at the constructor level, without the need for a function. Opening up the constructor is not an option due to using typedi. You can access the playgrou ...

Can a blob file be transformed into base64Data using Javascript specifically in Ionic and Angular frameworks?

https://i.stack.imgur.com/3aMyx.png[ async FileZip() { const code = await fetch("./assets/input.txt") var blob = await downloadZip([code]).blob() console.log(blob); function blobToBase64(blob: Blob): Observable<string> { r ...

Issue with the drag functionality of Framer Motion carousel causing malfunction

Attempting to create a basic Image Carousel using framer-motion for added functionality. The goal is to incorporate both buttons and drag control for sliding through the images. Currently, it functions properly, but if the slider overshoots on the last im ...

execute a rigorous compilation during the ng build angular process

I am currently working on a project using angular-cli and I have configured my package.json with the following scripts: "scripts": { "ng": "ng", "build": "ng build --base-href /test/", "prod": "ng build --prod --base-href /test/" } According to the ...

Tips on injecting configuration into forRoot

Is there a method to inject configuration object into AppModule's forRoot() function? How can I access the configService if there is no constructor within the module? config.yml: smtp: host: 'smtp.host.com' port: 10 secure: true aut ...

Developing an exportable value service type in TypeScript for AngularJS

I have been working on creating a valuable service using typescript that involves a basic switch case statement based on values from the collection provided below [{ book_id: 1, year_published: 2000 }, { book_id: 2, year_publish ...

Incorporate an image icon into an Angular grid

Currently, I am in the process of building a web application using Angular. The main goal is to create a grid and color specific cells based on data input. Below is the snippet of my HTML code: <mat-grid-list cols="10"> <mat-grid-tile * ...

Managing numerous post requests with Angular

Dealing with a large form containing HTML input elements, I have implemented a functionality where a POST request is made to a WebAPI whenever there is a change in the input value. Sometimes, multiple POST requests are triggered within seconds, causing da ...