Issue
I have an interfaces defined in Angular which are as below:
export interface User {
name: string;
address:string;
gender:string;
car: Cars[];
}
export interface Cars {
id: Number;
company: CarCompany;
model: CarModel;
parts: CarPartName[];
registrationAndBillingDate: RegistrationAndBillingDate[];
}
export interface RegistrationAndBillingDate {
id: Number;
registrationDate: Date;
billingDate: Date;
}
export class CarCompany {
id: number;
name: string;
}
export class CarModel {
id: number;
name: string;
}
export class CarPartName {
id: number;
name: string;
}
Following is my JSON response for the User object:
{
"name": "Tony",
"address": "NYC",
"gender": "male",
"cars": [
{
"carCompany": {
"id": 2
},
"carModel": {
"id": 1
},
"carParts": [
{
"partName": {
"id": 1
},
"available": null
},
{
"partName": {
"id": 2
},
"available": null
}
],
"carRegistartaionAndBillingDate": [
{
"registrationDate": "2022-04-15",
"billingDate": "2022-04-15"
}
]
}
]
}
For these type of users I am creating a table to list all of them in one page with more information in nested table as below:
Header will have properties from User interface and the table inside will have information from Cars table as below:
name address gender
row (when clicked) Tony NYC male
nested table company model parts
[object] [object] [object] //show name insted of object here
I am trying to create nested mat table I am able to fetch the name, address and gender from User but for nested table that appear on row click comes as a object as they are. I want to have name property to be displayed for company, model and parts column in nested table on row click instead of object. I have following code in ts file:
dataSource: Observable<[User]>;
displayedColumns: string[] = ['name', 'address', 'gender'];
expandedElement: User | null;
innerDisplayedColumns = ['company', 'model', 'parts'];
user: UserDataSource[] = [];
usersData: UserDataSource[] = [];
dataSource1 = new MatTableDataSource();
getAllUsersData() {
this.users.forEach(user => {
if (user.cars && Array.isArray(user.cars) && user.cars.length) {
this.usersData= [...this.usersData, { ...user, cars: new MatTableDataSource(user.cars) }];
} else {
this.usersData= [...this.usersData, user];
}
});
this.dataSource1 = new MatTableDataSource(this.usersData);
}
}
And in html template I have code like below:
<table mat-table [dataSource]="dataSource" multiTemplateDataRows class="mat-elevation-z8">
<ng-container matColumnDef="{{column}}" *ngFor="let column of displayedColumns">
<th mat-header-cell *matHeaderCellDef> {{column}} </th>
<td mat-cell *matCellDef="let element"> {{element[column]}} </td>
</ng-container>
<ng-container matColumnDef="expandedDetail">
<td mat-cell *matCellDef="let element" [attr.colspan]="displayedColumns.length">
<div class="example-element-detail" [@detailExpand]="element == expandedElement ? 'expanded' : 'collapsed'">
<div style="align-content: center;" class="example-container mat-elevation-z24">
<table #innerTables mat-table #innerSort="matSort" [dataSource]="element.cars" matSort>
<ng-container matColumnDef="{{innerColumn}}" *ngFor="let innerColumn of innerDisplayedColumns">
<th mat-header-cell *matHeaderCellDef mat-sort-header> {{innerColumn}} </th>
<td mat-cell *matCellDef="let element"> {{element[innerColumn]}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="innerDisplayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: innerDisplayedColumns;"></tr>
</table>
</div>
</div>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let element; columns: displayedColumns;" class="example-element-row"
[class.example-expanded-row]="expandedElement === element"
(click)="expandedElement = expandedElement === element ? null : element">
</tr>
<tr mat-row *matRowDef="let row; columns: ['expandedDetail']" class="example-detail-row"></tr>
</table>
So how to map object property in my case name in place of object in inner table or nested table. I have taken help from this Stackblitz link : [https://stackblitz.com/edit/angular-nested-mat-table] Any kind of help or suggestion would be highly appreciated. Thanks in advance.
Solution
It is pretty simple to display object's field in place of object itself. We can basically access object field in a column as follows:
<ng-container *matHeaderRowDef="company">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Company Name</th>
<td mat-cell *matCellDef="let element"> {{element.object?.fieldName}} </td>
</ng-container>
In my case it is as follows:
<ng-container *matHeaderRowDef="company">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Company Name </th>
<td mat-cell *matCellDef="let element"> {{element.company?.name}} </td>
</ng-container>
I hope it might be helpful for anyone else facing same problem. Thank You.
Answered By - Aaron
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.