Display multiple roles of a user in different rows using mat-table

Viewed 41

I want to display multiple roleName of User in Role column but in different rows using mat-table

I am making an API GET request to display user and there roles. Here is the sample JSON that is returning back.

[{
    firstName: 'User',
    lastName: '1',
    roles: [
        {id: '1', roleName: 'first Role'},
        {id: '2', roleName: 'second Role'}
        ]
}, {
    firstName: 'User',
    lastName: '2',
    roles: [
        {id: '1', roleName: 'third Role'},
        {id: '2', roleName: 'fourth Role'}
        ]
}];

UserDisplay.html

<section>
  <mat-table class="matTable" [dataSource]="dataSource">
    <ng-container matColumnDef="firstName">
      <mat-header-cell *matHeaderCellDef> First Name </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.firstName}} </mat-cell>
    </ng-container>

    <ng-container matColumnDef="lastName">
      <mat-header-cell *matHeaderCellDef> Last Name </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.lastName}} </mat-cell>
    </ng-container>

    <ng-container matColumnDef="roles">
      <mat-header-cell *matHeaderCellDef> Roles </mat-header-cell>
      <mat-cell *matCellDef="let row">        
        <ng-container *ngFor="let role of row.roles">
            {{role.roleName}}  
        </ng-container>
        </mat-cell>
    </ng-container>

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

  </mat-table>
</section>

user.component.ts

import { MatTableDataSource } from '@angular/material';

export class UserComponent implements OnInit {
    this.displayedColumns = ['firstName', 'lastName', 'roles'];
    this.dataSource.data = this.User;
}

I tried to user ngFor inside mat-cell but its throwing error. I want to iterate over multiple roles of user and display it each in a seperate different rows. for example

firstName lastName Role
User 1 First Role
User 1 second Role
User 2 third Role
User 2 fourth Role
1 Answers

You need to provide the data in the format you want to see on the screen.

Hence create a list of object that already has { roleName: 'first Role', firstName: 'User', lastName: '1'}

We are using flatMap to bring out the nested array and create a new object rather than edit the existing object. could also use Object.assign

let User = [{
      firstName: 'User',
      lastName: '1',
      roles: [{
          id: '1',
          roleName: 'first Role'
        },
        {
          id: '2',
          roleName: 'second Role'
        }
      ]
    }, {
      firstName: 'User',
      lastName: '2',
      roles: [{
          id: '1',
          roleName: 'third Role'
        },
        {
          id: '2',
          roleName: 'fourth Role'
        }
      ]
    }];

    let UserList = User.flatMap(p => p.roles.map(r =>  ({
      firstName: p.firstName,
      lastName: p.lastName,
      role: r.roleName
    })))

    console.log(UserList)

Now you can directly put the column here:

   <ng-container matColumnDef="role">
  <mat-header-cell *matHeaderCellDef> Role Name </mat-header-cell>
  <mat-cell *matCellDef="let row"> {{row.role}} </mat-cell>
</ng-container>
Related