Search code examples
htmlarraysangularngfor

how to retrieve the value from nested object arrays angular


I have an array of objects with nested arrays as shown below. How can I print the nested array values in a table using ngFor. The array looks as follows: enter image description here

I am using a table to print this values so I can export the table to Excel sheet.

The table looks as follows:

   <table class="table table-bordered">
            <thead class="thead-dark">
                <tr>
                    <th>Hours</th>
                    <th>Dates</th>
                    <th>Project Codes</th>
                </tr>
            </thead>
            <tbody class="tbody" *ngFor="let value of array; let i = index">
                <tr *ngFor="let item of array[i].item; let dateValue of array[i].datesArray; let h of array[i].hours">
                    <td>{{h}}</td>
                    <td>{{dateValue}}</td>
                    <td>{{value.projectCodeInput}}</td>
                </tr>
            </tbody>
        </table>

I am using multiple arrays on single tag in ngFor like this: {*ngFor="let item of array[i].item; let dateValue of array[i].datesArray; let h of array[i].hours"} I know this is wrong way, but somehow the hours prints in the output in both places overriding the dateValue in second column.

Is there a way to print the values from hours, dateValue array in the same element(TABLE)?


Solution

  • Instead of having multiple inputs to the *ngFor directive, you could move the let i=index to the inner loop and use it to get the values.

    I assume all the sub-arrays will always be of equal length i.e. hours, datesArray and item array will always be of equal length.

    If you wish to span the projectCodeInput property across multiple rows since it'll be the same for each element of the parent array, you could do so using [attr.rowspan] property and first local variable of the *ngFor directive. The check is to make sure the span element is rendered only once for the loop.

    <table class="table table-bordered">
      <thead class="thead-dark">
        <tr>
          <th>Hours</th>
          <th>Dates</th>
          <th>Project Codes</th>
        </tr>
      </thead>
      <tbody class="tbody" *ngFor="let element of arr">
        <tr *ngFor="let item of element.item; let i=index; let f=first">
          <td>{{element.hours[i]}}</td>
          <td>{{element.datesArray[i]}}</td>
          <td *ngIf="f" [attr.rowspan]="element.item.length">{{element.projectCodeInput}}</td>
        </tr>
      </tbody>
    </table>
    

    Working example: Stackblitz