How can I iterate over nested objects using ngFor in Angular HTML?

We have a data object stored on our server structured like this;

{
    "NFL": {
        "link": "https://www.nfl.com/",
        "ticketPrice": 75
    },
    "MLB": {
        "link": "https://www.mlb.com/",
        "ticketPrice": 60
    },
    "NHL": {
        "link": "https://www.nhl.com/",
        "ticketPrice": 55
    },
    "MLS": {
        "link": "https://www.mlssoccer.com/",
        "ticketPrice": 45
    }
}

To access this object, I have subscribed to it using the following code;

sportsObject : Sports[] //THIS IS THE MEMBER THAT SHOULD BE FILLED WITH THE JSON OBJECT GIVEN
object = Object;
ngOnInit(){
    this.SportsService.getPrices().subscribe(data=>{
      this.sportsObject = data;
    })    
}

Below is my html code for displaying the data;

   <div *ngFor="let key of Object.keys(sportsObject)">
       <p>The {{key}} is {{{{sportsObject[key]}}</p>
   </div>

However, I am encountering the error message, "Cannot find a differ supporting object '[object Object]' of type 'object'." How can I rectify this issue and successfully iterate through this JSON object?

Answer №1

*ngFor directive typically works with arrays. However, for iterating over objects, you can utilize the keyvalue pipe (Angular v6.1.0+). Give this code snippet a try:

<div *ngFor="let sport of sportsObject | keyvalue">
  <p>The {{ sport.key }} is {{ sport.value.ticketPrice }}</p>
  <p>More Info: <a [attr.href]="sport.value.link">{{ sport.value.link }}</a></p>
</div>

Additionally, it's recommended to avoid invoking functions in directive bindings ([dir]="someFunc()" and *dir="someFunc()") as well as interpolations ({{ someFunc() }}). This practice can help prevent performance issues, especially if you don't have control over the change detection strategy.

Answer №2

Store keys as an array in your TypeScript file

this.sportsObject = data;
this.keys= Object.keys(data);

Then, in your HTML template, directly utilize this array

<div *ngFor="let key of keys">
    <p>Key is: {{ key }}</p>
    <p>{{ sportsObject[key].link }}</p>
    <p>{{ sportsObject[key].ticketPrice }}</p>
</div>

Answer №3

To utilize the `keyvalue` pipe, simply include it in your code. Additionally, I suggest using the `async` pipe instead of directly assigning data from the API to the `sportsObject`. Your code could resemble the following:

TS:

sports$: Observable<Sports>;    

ngOnInit(){
  this.sports$ = this.SportsService.getPrices();
}

HTML:

<div *ngFor="let sport of (sports$ | async) | keyvalue">
   <p>The {{sport.key}} is {{sport.value}}</p>
</div>

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

How to locate a specific object by its ID within a JSON structure embedded in an HTML template

I am currently working on the page where I display posts. Within my controller, I have: export class PostsComponent implements OnInit { posts$: Object; users$: Object; constructor(private data: DataService) { } ngOnInit() { this.data.getPo ...

Tips for connecting to a docker container containing an Angular application while the Angular app is also running in its own container

I have encountered an issue with my application that consists of a frontend and a backend running together in a Docker compose container. The backend has been functioning well without any problems during development, but the frontend, which is an Angular a ...

Troubleshooting mat-accordion title problem on mobile devices

Despite reading numerous blogs and conducting extensive searches on Google, I am still unable to resolve the CSS issue related to Angular material below. Your assistance in fixing this problem would be greatly appreciated. Desktop view: https://i.stack.im ...

Currently in the process of optimizing controllers but continuously encountering 404 errors when making api requests

I previously utilized the SampleData controller that is automatically generated. I added my custom methods, everything was functioning perfectly. Recently, I decided to create a new class for better organization purposes. After pasting in the desired metho ...

Extract nested values within objects and arrays, and return the complete type of the original object

I have a dataset that resembles the structure of IconItems: { title: "Category title", description: "Example description", lists: [ { id: "popular", title: "Popular", items: [ { ...

How to make a node application run as an executable within an NX workspace

The structure of an NX workspace really caught my attention, which led me to start using it for a new CLI project I was working on. I began by setting up a @nrwl/node:application, but I'm currently facing some issues trying to make it executable. I ...

Error encountered in Typescript: SyntaxError due to an unexpected token 'export' appearing

In my React project, I encountered the need to share models (Typescript interfaces in this case) across 3 separate Typescript projects. To address this, I decided to utilize bit.env and imported all my models to https://bit.dev/model/index/~code, which wor ...

RestSharp request encountered HTTP Error 406 during execution

I am attempting to establish a connection to a server using RestSharp, but I keep receiving an HTTP Error 406 Not acceptable. Here is the response from the web service: {"metaInfo":{"ErrorString":" ","ErrorCode":" ","Result":true},"userModel":{"UserId":"1 ...

Unexpected Typescript error when React component receives props

I encountered an unexpected error saying ": expected." Could it be related to how I'm setting up props for the onChange event? Here is my code for the component: import React from "react"; interface TextFieldProps { label?: string; ...

Clearing Out a Shopping Cart in Angular

Hey there, I have a little dilemma with my shopping cart system. I can easily add and delete products using an API. However, when it comes to deleting an item from the cart, I have to do it one by one by clicking on a button for each item, which is not ver ...

When I define a type in TypeScript, it displays "any" instead

Imagine a scenario where we have a basic abstract class that represents a piece in a board game such as chess or checkers. export abstract class Piece<Tags, Move, Position = Vector2> { public constructor(public position: Position, public tags = nul ...

A warning has been issued: CommonsChunkPlugin will now only accept one argument

I am currently working on building my Angular application using webpack. To help me with this process, I found a useful link here. In order to configure webpack, I created a webpack.config.js file at the package.json level and added the line "bundle": "web ...

"Uploading user profile images with Angular, Express, Multer, and Mongoose made easy

Hey there, I'm currently using multer to upload images. When I select an image, it gets saved in the backend folder called uploads. However, I would like to store it in a MongoDB database and then display that image on the frontend using Angular. I&ap ...

PHP: Convert a complex JSON into a CSV format

Seeking a solution to convert a JSON string into a CSV file with specific content: "ID","NAME","PHONE_WORK","PHONE_MOBILE","COMPANY" In the provided JSON string: "00003015000003","Christian X","","0043 699 23231","X"<br/> ....<br/> ... This ...

I need help differentiating "namespace" from "static attributes" in TypeScript

Separating namespace from static properties in TypeScript can sometimes be tricky. error: 'ClassA' only refers to a type, but is being used as a namespace here. class ClassA { static ClassB = class { }; } type T = ClassA // ok type T = C ...

Exploring the power of Vue3 with reactive nested objects and the inclusion of

It seems like I've encountered a bit of a challenge... Perhaps a bug in Vue3 with Typescript and the composition API, or maybe I'm missing something. I'm facing an issue where I'm not getting any intellisense in my IDE (Webstorm) when ...

How to apply CSS classes to dynamically injected HTML in Angular 7

One of the challenges I'm currently facing is how to assign a CSS class based on a calculation in my component. Here's a snippet from my component class: @Component({ selector: 'app-render-json', template: `<div [innerHtml ...

Personalize JSON Output

Currently, I am working on incorporating jqvmap into my project. The original format of my json response is as follows: [ { "Count": 10, "ProvinceCode": 34 }, { "Count": 6, "ProvinceCode": 59 } The required format for jqvmaps is as shown ...

How can you create a function in typescript that only allows parameters of a specific type?

Here's what I'm trying to accomplish: function validateNumber(param: ???): param is number { } If the parameter can be a number, such as number | string or number | boolean, it should be accepted by the function. However, if the type is somethin ...

Submitting a nested JSON body in ASP MVC

I'm currently struggling to send a nested JSON body to an API, and I've tried a few different approaches without success. The JSON values are sourced from multiple models, making it quite complex for me to handle. Any assistance or guidance on th ...