2

I am showing the data of my JSON file in the mat-table. The mat-table works fine in showing the rows but I have to show the data inside an array in a row. However, I don't know what would be the best predicate to use. I tried where predicate but it didn't work.

Data:

{
  "fname": "Mark",
  "lname": "jhony",
  "parcels": [
    {
      "parcelId": 123,
      "parcelName: "asd",
      "parcelItems": [
        { 
          "itemId": 2,
          "itemName": "perfume"
        },
        { 
          "itemId": 4,
          "itemName": "soap"
        }
      ]
    },
    {
      "parcelId": 144,
      "parcelName": "parcel2",
      "parcelItems": [
        { 
          "itemId": 2,
          "itemName": "headphones"
        },
        { 
          "itemId": 4,
          "itemName": "mouse"
        }
      ]
    }
  ]
}

HTML template:

<table mat-table [dataSource]="dataSource" matSort>
  <ng-container matColumnDef="fname">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> Fname </th>
    <td mat-cell *matCellDef="let element"> {{element.fname}} </td>
  </ng-container>
  <ng-container matColumnDef="lname">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> Lname </th>
    <td mat-cell *matCellDef="let row"> {{row.lname}} </td>
  </ng-container>
  <ng-container matColumnDef="parcelid">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> Parcelid </th>
    <td mat-cell *matCellDef="let element"> {{element.parcels[0].parcelId}} </td>

  </ng-container>
  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row;columns: displayedColumns;"></tr>
</table>

Here i can access the parcelId, like above element.parcels[0].parcelId. However, I want to make it repeat so the fname, lname and all the parcels of a particular user can be seen in the table

2
  • Is it intentional that your JSON data is missing some quotation marks? Commented Oct 28, 2018 at 15:27
  • sorry i edited the data and missed to add the quotation marks Commented Oct 29, 2018 at 10:16

2 Answers 2

5

If you know the number of parcels beforehand, and it is a fixed number, you could use ngFor in the HTML template and a for-loop when fetching data, before setting the data source, to fill in the correct number and names of displayed columns. If you don't have this information, you could always use ngFor in the template alone, listing all the data in a cell like this: https://stackblitz.com/edit/nested-table-data

<ng-container matColumnDef="parcels">
    <mat-header-cell *matHeaderCellDef> Parcels </mat-header-cell>
    <mat-cell *matCellDef="let element">
        <div class="parcels">
            <ng-container *ngFor="let parcel of element.parcels">
                <div class="parcel">
                    <ul>
                        <li>ID: {{parcel.parcelId}}</li>
                        <li>Name: {{parcel.parcelName}}</li>
                    </ul>
                    <ul>
                        <li *ngFor="let item of parcel.parcelItems">
                            <span>{{item.itemId}}: {{item.itemName}}</span>
                        </li>
                    </ul>
                </div>
            </ng-container>
        </div>
    </mat-cell>
</ng-container>
Sign up to request clarification or add additional context in comments.

Comments

2

The easiest way i found is to rearrange the array and make it accordingly to the table. This way i also able to achieve sorting and filter too in table .

1 Comment

My case is more complex, and object from AWS Cognito that includes arrays of arrays of objects, the user attributes and such. Mat Table reads the first level after I extract that level from the main object but not the lower ones. They have to be brought up the the first level as you suggest. Pain to code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.