Alan Mark Kristensen
Alan Mark Kristensen

Reputation: 129

Using Angular NgFor to fill html data table with data from JSON array

I'm translating massive excel spreadsheets into json, then building a tool to format the data and utilize it for analysis.

In the upload process, i'm presenting the user with a view of all their data. I'm having some trouble formatting the tables though and i'm hoping someone here can help explain the problem:

When using standard data tables in html i can get my desired result easily when hardcoding it:

<div style="margin-bottom: 10px">
    <table class="table table-responsive table-condensed">
      <tr>
        <th style="color: black" *ngFor="let label of lineChartLabels">{{label}}</th>
      </tr>
      <tr *ngFor="let d of XLSData">
        <td>This is in Column 1</td>
        <td>And this is in Column 2</td> 
      </tr>
    </table>
  </div>

And i get this: correctTables But when filling the rows with NgFor i get the data repeated for every column:

<div style="margin-bottom: 10px">
    <table class="table table-responsive table-condensed">
      <tr>
        <th style="color: black" *ngFor="let label of lineChartLabels">{{label}}</th>
      </tr>
      <tr *ngFor="let d of XLSData">
        <td style="color: black" *ngFor="let label of lineChartLabels">Time: {{d.Time | json}}</td>
        <td style="color: black" *ngFor="let label of lineChartLabels">Empty: {{d.__EMPTY | json}}</td>
      </tr>
    </table>
  </div>

I get this: wrongTables

I don't understand why the loop fills up every column available with the same data, as the data does not repeat in the JSON array.

Upvotes: 0

Views: 2104

Answers (2)

Richard Pariath
Richard Pariath

Reputation: 160

The way you are using ngFor is mistaken. ngFor will iterate for the number of times either mentioned explicitly using an index or for the number of elements present inside the looping object. In your case there are two elements and so it's repeating twice.

  <tr>
    <th style="color: black" *ngFor="let label of lineChartLabels">{{label}}</th>
  </tr>
  <tr *ngFor="let d of XLSData">
    <td style="color: black">Time: {{d.Time | json}}</td>
    <td style="color: black">Empty: {{d.__EMPTY | json}}</td>
  </tr>

Just make these changes.

Upvotes: 1

Elias Soares
Elias Soares

Reputation: 10264

That's because you are doing two *ngFor on columns inside the tr of table body.

If you data always have the same columns, just hard-code it (no *ngFor needed for columns):

<div style="margin-bottom: 10px">
    <table class="table table-responsive table-condensed">
      <tr>
        <th style="color: black">Time</th>
        <th style="color: black">__EMPTY</th>
      </tr>
      <tr *ngFor="let d of XLSData">
        <td style="color: black">Time: {{ d.Time | json }}</td>
        <td style="color: black">Empty: {{ d.__EMPTY | json }}</td>
      </tr>
    </table>
</div>

If your columns are dynamic, then you need to *ngFor on columns:

<div style="margin-bottom: 10px">
    <table class="table table-responsive table-condensed">
      <tr>
        <th style="color: black" *ngFor="let label of lineChartLabels">
          {{ label }}
        </th>
      </tr>
      <tr *ngFor="let d of XLSData">
        <td style="color: black" *ngFor="let label of lineChartLabels">
          <!-- Note that I'm assuming here that your label is the same of your field name on `d`. If is not, you will need to better structure your code -->
          {{ d[label] | json }}
        </td>
    </table>
</div>

Upvotes: 1

Related Questions