I use the Angular Material table to display records inside a loop. According to my code, only one record is getting displayed. However, two records are coming from the response. Please review my array and code and provide me with a solution. The table is displayed like this:
Array:
[
{
"unitTypeSizeConcat": [
"HJHJ",
"ABC"
],
"list": [
{
"id": "6665c40f93ff924ef96e05de",
"subscriberId": "6331733aa38f414a418ab3fc",
"locationId": "64f85dff2f4280212657f7e7",
"description": "test",
"unitRateType": "Rented Unit Below Board Rate",
"unitRateTypeId": 1,
"rateChangeType": "Rotating Fixed Amount",
"value": "5",
"effectiveDate": "01/01/2024",
"recurringPeriod": "5",
"noticeDays": "5",
"applyBySize": true,
"applyByUnit": false,
"applyByUnitSizeCode": "6662dc6325bec37c0cedf0d9",
"applyByUnits": [],
"applyByUnitId": "MongoObjectId(id=null)",
"applyByUnitName": null,
"revisionHistory": 0,
"unitTypeSizeConcat": "HJHJ;ABC",
"lastRateChangeDate": null,
"lastRateChangeAmount": null,
"noticeDate": null
},
{
"id": "66f4f05eb5c2b8424c431fc7",
"subscriberId": "6331733aa38f414a418ab3fc",
"locationId": "64f85dff2f4280212657f7e7",
"description": "ghgh",
"unitRateType": "Rented Unit Below Board Rate",
"unitRateTypeId": 1,
"rateChangeType": "Rotating Fixed Amount",
"value": "2",
"effectiveDate": null,
"recurringPeriod": "2",
"noticeDays": "2",
"applyBySize": true,
"applyByUnit": false,
"applyByUnitSizeCode": "6662dc6325bec37c0cedf0d9",
"applyByUnits": [
"666ab7306ac32055804a25b5",
"666bdba59783af20ce55b5ff",
"6679aba38a764d4b153d6d8d",
"667aac1bbcb1e01439e96368",
"667d1b6d0306513a6c75ed30",
"66c5d8e97cf2c6598e91c134"
],
"applyByUnitId": "000000000000000000000000",
"applyByUnitName": null,
"revisionHistory": 0,
"unitTypeSizeConcat": "HJHJ;ABC",
"lastRateChangeDate": null,
"lastRateChangeAmount": null,
"noticeDate": null
}
]
}
]
HTML:
<div *ngFor="let rc of filteredSizeCode" class="table-responsive table-content">
<h3 class="text-primary mt-1 mb-3">Unit Type : {{rc.unitTypeSizeConcat[0]}}</h3>
<table mat-table [dataSource]="datasource" matSort class="mat-elevation-z8" matSortDisableClear>
<ng-container matColumnDef="unitRateType">
<th class="centered-sorted-header" mat-header-cell *matHeaderCellDef mat-sort-header>Unit Rate Filter</th>
<td mat-cell *matCellDef="let row; let i=index">{{row.list[i].unitRateType}}</td>
</ng-container>
<ng-container matColumnDef="rateChangeType">
<th class="centered-sorted-header" mat-header-cell *matHeaderCellDef mat-sort-header>Rate Change Type</th>
<td mat-cell *matCellDef="let row; let i=index">{{row.list[i].rateChangeType}}</td>
</ng-container>
<ng-container matColumnDef="effectiveDate">
<th class="centered-sorted-header" mat-header-cell *matHeaderCellDef mat-sort-header>Effective Date</th>
<td mat-cell *matCellDef="let row; let i=index">{{row.list[i].effectiveDate | date: 'MM-dd-yyyy'}}</td>
</ng-container>
<ng-container matColumnDef="noticeDays">
<th class="centered-sorted-header" mat-header-cell *matHeaderCellDef mat-sort-header>Notice Days</th>
<td mat-cell *matCellDef="let row; let i=index ">{{row.list[i].noticeDays}}</td>
</ng-container>
<ng-container matColumnDef="value">
<th style="padding-left:28px;" mat-header-cell *matHeaderCellDef mat-sort-header>Value</th>
<td mat-cell *matCellDef="let row; let i=index">{{row.list[i].rateChangeType == 'Rotating Fixed Amount' || row.list[i].rateChangeType == 'One Time Only Fixed Amount'?'$':null }}
{{row.list[i].value}}{{row.list[i].rateChangeType == 'Rotating Fixed Percentage' || row.list[i].rateChangeType == 'One Time Only Fixed Percentage'?'%':null}}
</td>
</ng-container>
<ng-container matColumnDef="recurringPeriod">
<th style="padding-left:28px;" mat-header-cell *matHeaderCellDef mat-sort-header>Recurring Period</th>
<td mat-cell *matCellDef="let row; let i=index">{{row.list[i].recurringPeriod?row.list[i].recurringPeriod:null}}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
</div>
ts code:
displayedColumns = [
'unitRateType',
'rateChangeType',
'effectiveDate',
'noticeDays',
'value',
'recurringPeriod',
];
datasource = new MatTableDataSource([]);
ngOnInit() {
this.datasource.data = this.filteredSizeCode;
}
Before answering your problem regarding not being able to display all the records from the list
array, my concern is that you are iterating the filteredSizeCode
in the view, and at the same time, there is only 1 MatTableDataSource
which is shared with the data filteredSizeCode
.
This works if you only have a single entry in the filteredSizeCode
array. If you have multiple entries, I am sure that in each iterated rc
element, your <mat-table>
will display those data that shouldn't belong to the rc
element.
The correct way is you need to create the MatTableDataSource
instance(s) for each rc
element and not to share it.
Back to your problem, i
(in the View) is the index referring to the row of filteredSizeCode
(root array), not the list
array from each element. Hence, it will never display the second items and so on for the list
array.
In that case, you need to flatten the list
array from each element.
Changes
Flatten the list
array from each element.
Create each MatTableDataSource
instance for each element in the filteredSizeCode
array.
datasources: MatTableDataSource<any[]>[] = [];
ngOnInit() {
this.filteredSizeCode.forEach((size: any) => {
let data: any[] = size.list.map((x: any) => ({ ...size, list: x}))
this.datasources.push(new MatTableDataSource(data));
})
}
Provide the MatTableDataSource
instance based on the current iterated index from the rc
element.
Remove [i]
from the list
as it is flattened to an object.
<div *ngFor="let rc of filteredSizeCode; let i = index" class="table-responsive table-content">
<h3 class="text-primary mt-1 mb-3">
Unit Type : {{rc.unitTypeSizeConcat[0]}}
</h3>
<table
mat-table
[dataSource]="datasources[i]"
matSort
class="mat-elevation-z8"
matSortDisableClear
>
<ng-container matColumnDef="unitRateType">
<th
class="centered-sorted-header"
mat-header-cell
*matHeaderCellDef
mat-sort-header
>
Unit Rate Filter
</th>
<td mat-cell *matCellDef="let row; let i=index">
{{row.list.unitRateType}}
</td>
</ng-container>
<ng-container matColumnDef="rateChangeType">
<th
class="centered-sorted-header"
mat-header-cell
*matHeaderCellDef
mat-sort-header
>
Rate Change Type
</th>
<td mat-cell *matCellDef="let row; let i=index">
{{row.list.rateChangeType}}
</td>
</ng-container>
<ng-container matColumnDef="effectiveDate">
<th
class="centered-sorted-header"
mat-header-cell
*matHeaderCellDef
mat-sort-header
>
Effective Date
</th>
<td mat-cell *matCellDef="let row; let i=index">
{{row.list.effectiveDate | date: 'MM-dd-yyyy'}}
</td>
</ng-container>
<ng-container matColumnDef="noticeDays">
<th
class="centered-sorted-header"
mat-header-cell
*matHeaderCellDef
mat-sort-header
>
Notice Days
</th>
<td mat-cell *matCellDef="let row; let i=index ">
{{row.list.noticeDays}}
</td>
</ng-container>
<ng-container matColumnDef="value">
<th
style="padding-left: 28px"
mat-header-cell
*matHeaderCellDef
mat-sort-header
>
Value
</th>
<td mat-cell *matCellDef="let row; let i=index">
{{ row.list.rateChangeType == 'Rotating Fixed Amount' || row.list.rateChangeType == 'One Time Only Fixed Amount' ? '$' : null }}
{{ row.list.value }} {{ row.list.rateChangeType == 'Rotating Fixed Percentage' || row.list.rateChangeType == 'One Time Only Fixed Percentage' ? '%' : null }}
</td>
</ng-container>
<ng-container matColumnDef="recurringPeriod">
<th
style="padding-left: 28px"
mat-header-cell
*matHeaderCellDef
mat-sort-header
>
Recurring Period
</th>
<td mat-cell *matCellDef="let row; let i=index">
{{row.list.recurringPeriod ? row.list.recurringPeriod : null}}
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
</div>