Attempting to iterate through an array of objects using ngFor and utilizing a separate array of header objects to populate a table

I have a requirement to display an array of objects in a table component within the CollectionsHome Component

CollectionsHomeComponent:

import { Component, OnInit } from '@angular/core';

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

  data = [
    {name: 'James', age: 24, job: 'Designer'},
    {name: 'Jill', age: 26, job: 'Engineer'},
    {name: 'Elyse', age: 25, job: 'Engineer'}
  ];

  headers=[
    {key:'name', label: 'Name'},
    {key:'age', label: 'Age'},
    {key:'job', label: 'Job'}
  ]

  constructor() { }

  ngOnInit(): void {
  }
}

TableComponent

import { Component, OnInit, Input } from '@angular/core';

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

  @Input() data: {name: string; age: number; job: string}[] = [];
  @Input() headers: {key: string; label: string}[] = [];

  constructor() { }

  ngOnInit(): void {
  }

}

CollectionsHomeComponent.html

<app-divider>Table Component</app-divider>
<app-table [data]="data" [headers]="headers"></app-table>

TableComponent.html
I am using ngfor to iterate through the objects in the data array based on the keys provided in the headers

<table class="ui table">
    <thead>
        <tr>
            <th *ngFor="let header of headers">
                {{header.label}}
            </th>
        </tr>
    </thead>
    <tbody>
        <tr *ngFor="let record of data">
            <td *ngFor="let header of headers">
                {{record[header.key]}}  ---> Throwing Error
            </td>
        </tr>
    </tbody>
</table>

The code {{record[header.key]}} is causing an error and I'm unsure why

Here is the error message:

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ name: string; age: number; job: string; }'.
 No index signature with a parameter of type 'string' was found on type '{ name: string; age: number; job: string; }'.ngtsc(7053)
table.component.ts(4, 40): Error occurs in the template of component TableComponent.

The only workaround I found is by changing the input types to any like this

import { Component, OnInit, Input } from '@angular/core';

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

  @Input() data: any = [];
  @Input() headers: any = [];

  constructor() { }

  ngOnInit(): void {
  }

}

Can someone help me understand why? I feel like using any in cases like this is not best practices

Answer №1

Specify the structure of the table header and data type as follows:

export interface TableDataType {
  name: string;
  age: number;
  job: string;
}

export interface TableHeader {
  key: string;
  label: string;
}

Then implement it in the table component:

@Component({
  selector: 'app-table',
  templateUrl: './table.component.html',
})
export class TableComponent implements OnInit {
  @Input() data: Array<TableDataType>[];
  @Input() headers: Array<TableHeader> = [];

  constructor() {}

  ngOnInit(): void {}
}

Check out the live example here: https://stackblitz.com/edit/angular-2khgqx?file=src/app/table-demo/table.component.ts

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

Issue with bidirectional data binding in Angular 2 on input element not functioning as expected

Looking at the code snippet below, I have noticed that even though the textchange function is called when the input value changes, the text property of the InputMaskComponent remains constant. I am not able to identify the issue in my code. InputMaskCompo ...

A guide on incorporating ng2-canvas-whiteboard into your Ionic 3 project

I'm trying to implement the npm package ng2-canvas-whiteboard into my Ionic 3 app. I followed all the instructions on the npm page and here is my package.json: "dependencies": { "@angular/common": "4.0.2", "@angular/compiler": "4.0.2", ...

Issue with Ionic Framework Typescript: `this` variables cannot be accessed from callback functions

Is it possible for a callback function to access the variables within this? I am currently working with d3.request and ionic 3. I can successfully make a REST call using d3.request, but I am facing difficulty when trying to assign the response to my this. ...

The Typescript compiler has trouble locating the definition file for an npm package

Recently, I released an npm package that was written in typescript. However, I have been facing difficulties in getting the definition recognized by typescript (webback and vscode). The only workaround that has worked for me so far is creating a folder wit ...

The Angular 2 service is not transmitting the POST data in the correct format, although it functions properly when transmitted through PostMan

When the POST data is transmitted from the Angular 2 service in this manner: const data = new FormData(); data.append('date', '12/01'); data.append('weight', '170'); return this.http.post(this.u ...

Tips for successfully sending dynamic values to a modal with Angular 2

Greetings! I am currently working with dynamic data that is being displayed in the form of buttons. Below you will find the code snippet: <ng-container *ngFor="let data of mapData"> <div *ngIf="data.OrderState===&ap ...

When there is data present in tsconfig.json, Visual Studio Code does not display errors inline for TypeScript

After creating an empty .tsconfig file (consisting solely of "{ }"), Visual Studio Code immediately displays errors both inline and in the "problems" section. Interestingly, when I populate the tsconfig.json file with data, these errors disappear. Is there ...

experimenting with a TypeScript annotation

I have created a simple decorator that can trigger either stopPropagation() or preventDefault() based on certain conditions. I have thoroughly tested this decorator in my application and am confident that it works correctly. However, I encountered an issue ...

Find your way to a specific segment of another page or component within Angular

When a link is clicked, I want to be able to navigate to a fragment on a different page or component. Despite trying various methods, I have not been successful in achieving this. Here is what I have attempted: The link in question: <a routerLink=" ...

Two-way data binding between TypeScript and HTML FormGroups

Attempting to create my first Reactive form in Angular Here is the code : import { Component, OnInit } from '@angular/core'; import { FormGroup, FormControl } from "@angular/forms"; @Component({ selector: 'app-username-password ...

Using TypeScript to sort objects based on keys and convert an array of objects into a different object type

I'm facing an issue where I need to filter the objects within an array of objects based on keys and convert them into a different type of object. I attempted to solve it like this... const values = Object.keys(user).map((key) => {'refKey' ...

Mat-paginator in Angular does not show up in mat-table

While working with Angular 12, I have imported the mat-paginator component using the following code: import { MatPaginator } from '@angular/material/paginator'; Then, in the export section, I attempted to reference the paginator with both of the ...

Error: There was a problem trying to import the `.d.ts` file

Software Stack Vue version 3.2.19 @vue/test-utils version 2.0.0-rc.15 Typescript version 4.1.6 Issue Description Encountering an error when running the command vue-cli-service test:unit --no-cache. Please refer to the TypeError screenshot (link to Con ...

Is it feasible to replicate an error in TypeScript with certain modifications?

Currently, I'm facing a challenge where I need to utilize Sentry.captureException with an error that I have received. However, before doing so, I am attempting to modify the error message. Despite spending considerable time searching for a solution, I ...

What is the correct way to format React's dispatch function in order to utilize a "then" method similar to a Promise?

I'm working on a simple app that dispatches an action upon first load to populate the store. However, I'm facing an issue with trying to run a then method on dispatch, as typescript is throwing errors. (As per redux's documentation, the ret ...

Steps for modifying the look of a button to display an arrow upon being clicked with CSS

Looking to enhance the visual appearance of a button by having an arrow emerge from it upon clicking, all done through CSS. Currently developing a React application utilizing TypeScript. Upon clicking the next button, the arrow should transition from the ...

Leveraging React and TypeScript's capabilities to pass around arguments efficiently

As I integrate TypeScript into my application, I find myself at a juncture where I need to specify the following: { id, label, type, styles, ...props } Incorporating this structure into a component like the one below: const TestComponent = ({ id, label, t ...

What methods can be used to test scss subclasses within an Angular environment?

Exploring different background colors in various environments is a task I want to undertake. The environments include bmw, audi, and vw, with each environment having its own unique background color. Need help writing an Angular test for this? How can I mod ...

Error message: Typescript index signature issue - Cannot assign the argument of type to the parameter of type 'SetStateAction<never[]>'

As someone new to typescript and Index signatures, I am struggling to find a solution to the error in my code. It seems like I need to do something with the variable sortProperty on the sorted variable, but I can't seem to figure it out. I am encounte ...

Creating an Angular directive that captures and handles click events

Is there a way to create a directive that captures mouse click events on an entire component? I recently crafted an Angular directive specifically for capturing mouse clicks. @Directive({ selector: '[interceptClick]' }) export class Intercep ...