SkinnyBetas
SkinnyBetas

Reputation: 501

Trying to use Angular Material table on object that contains another object

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

Answers (2)

Eliseo
Eliseo

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

Lotte Lemmens
Lotte Lemmens

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

Related Questions