Reputation: 501
So basically I have an interface defined in Angular that looks something like this:
export interface product {
brand: String,
type: String,
value: number,
fields: Rating[]
}
the fields property is an array of Rating objects, the point being that the user can add numerous Ratings to the field property. The problem is that I can't work out how to essentially flatten this object onto the table so that all the fields just appear as another column.
brand type value field1 field2 field3
row1
row2
At the moment I have the html template iterating through the product object, although when you hit fields it does as you'd think and gives you a column of [Object object], [Object object]. Is there a way I could maybe have another nested loop inside my current loop... Or something along those lines. Current table code looks like this.
<mat-table [dataSource]="data">
<ng-container *ngFor="let col of columns" matColumnDef="{{col}}">
<mat-header-cell *matHeaderCellDef>{{ col }}</mat-header-cell>
<mat-cell *matCellDef="let element">
{{ element[col] }}
</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="columns"></mat-header-row>
<mat-row *matRowDef="let row; columns: columns;"></mat-row>
</mat-table>
Any help would be greatly appreciated.
Upvotes: 0
Views: 2082
Reputation: 57939
The same idea of LotteLemmens using pipe map in your service:
this.httpClient.get(...).pipe(map(data:any[]=>{
return data.map(r=>({
brand: r.brand,
type: r.type,
value: r.value,
fields1: r.rating[0],
fields2: r.rating[1],
fields3: r.rating[2]
}))
}))
Another idea is simply use {{col.indexOf('fields')>0?element[col][+col[6]-1]:element[col]}}
(*)
<ng-container *ngFor="let col of columns" matColumnDef="{{col}}">
<mat-header-cell *matHeaderCellDef>{{ col }}</mat-header-cell>
<mat-cell *matCellDef="let element">
{{col.indexOf('fields')>=0?element[col][+col[6]-1]:element[col]}}
</mat-cell>
</ng-container>
(*) when we use over a string variable[4]
get the character in position 5th, we convert in number (adding the +
and subtract 1) -usually it's prefer our fields was fields0, fields1 and fields2 to avoid the "substract", but it is our election.
Another aproach is to have a variable columnsWihoutFields
columnsWihoutFields="brand,type,value"
And make two loops:
<!--loop over columnsWithoutFields-->
<ng-container *ngFor="let col of columnsWihoutFields" matColumnDef="{{col}}">
<mat-header-cell *matHeaderCellDef>{{ col }}</mat-header-cell>
<mat-cell *matCellDef="let element">
{{ element[col] }}
</mat-cell>
</ng-container>
<!--loops to show the fields-->
<ng-container *ngFor="let col of [1,2,3]" matColumnDef="{{'fields'+col}}">
<mat-header-cell *matHeaderCellDef>{{ 'fields'+col}}</mat-header-cell>
<mat-cell *matCellDef="let element">
{{ element.ratting[col] }}
</mat-cell>
</ng-container>
NOTE: I suppose your columns are "brand,type,value,field1,field2,field3"
Upvotes: 2
Reputation: 581
Depeding on how you would like to see the result in your table, you'll have to manipulate the data before you send it to your table. If you cannot be sure there will always be exactly 3 fields you might want to reconsider your design to somehting that repeats its original data for each row.
For this case is think you might look for something like this:
let newlist=[];
fetchdata.subscribe(results=>{
results.foreach(r=>{
newlist.push({
brand: r.brand,
type: r.type,
value: r.value,
fields1: r.rating[0],
fields2: r.rating[1],
fields3: r.rating[2]
});
})
})
<mat-table [dataSource]="newlist">
Upvotes: 0