Home > Blockchain >  Angular: Dynamically find headers when converting JSON array to HTML table
Angular: Dynamically find headers when converting JSON array to HTML table

Time:05-14

In Angular, I want to convert a JSON array to an HTML table.

I have seen an old answer for AngularJS:

<table>
    <thead>
      <tr>
        <th ng-repeat="(key, value) in records[0]">{{key}}</th>
      </tr>
    </thead>
    <tbody>
      <tr ng-repeat="(key, value) in records">
        <td ng-repeat="(key, value) in value">
          {{value}}
        </td>
      </tr>
    </tbody>
</table>

JSON looks like this:

[{
    "Name": "Alfreds Futterkiste",
    "City": "Berlin",
    "Country": "Germany"
}, {
    "Name": "Berglunds snabbköp",
    "City": "Luleå",
    "Country": "Sweden"
}, {
    "Name": "Centro comercial Moctezuma",
    "City": "México D.F.",
    "Country": "Mexico"
}]

I've tried to translate it to the Angular syntax. Here is what I got so far:

<table>
    <thead>
      <tr>
        <th *ngFor="let item of records[0]  | keyvalue">{{item.key}}</th>
      </tr>
    </thead>
    <tbody>
      <tr *ngFor="let item of records">
        <td *ngFor="let item1 of item | keyvalue">
          {{item1.value}}
        </td>
      </tr>
    </tbody>
</table>

Right now it's failing to compile because records[0] is undefined... how can I translate this expression to the newer syntax (or create something equivalent)?

UPDATE:

I have a partial solution. However with this partial solution the rendered table is not completely identical to the older AngularJS rendition (because it creates multiple unnecessary header rows, which only one of them is populated, as opposed to only one header row in the older rendition).

<table style="border-collapse: collapse;">
    <thead *ngFor="let item of records; let last=last">
      <tr *ngIf="last">
        <th *ngFor="let item1 of item | keyvalue">
          {{item1.key}}
        </th>
      </tr>
    </thead>
    <tbody>
      <tr *ngFor="let item of records">
        <td *ngFor="let item1 of item | keyvalue">
          {{item1.value}}
        </td>
      </tr>
    </tbody>
</table>

Do you have a better way to do it, possibly similar to the older AngularJS version?

CodePudding user response:

I think maybe you need to define records in the component.

records = [{
    "Name": "Alfreds Futterkiste",
    "City": "Berlin",
    "Country": "Germany"
}, {
    "Name": "Berglunds snabbköp",
    "City": "Luleå",
    "Country": "Sweden"
}, {
    "Name": "Centro comercial Moctezuma",
    "City": "México D.F.",
    "Country": "Mexico"
}];

CodePudding user response:

I am fairly certain this is what you need: https://stackblitz.com/edit/angular-ivy-n7irpw?file=src/app/hello.component.ts

Take a look at how I import the file in the app.component.ts As well as how I loop in the HTML.

Let me know if it helps!

  • Related