jijo
jijo

Reputation: 815

Angular: MatSort not working when using object inside datasource

I have an angular 6 application which has a Mat Table. Data for the table is populated like below. Sorting works for the fields position and name, but not weight and symbol which are part of the detail object. I have also tried naming the columns like detail.weight in displayedColumns and matColumnDef but with no luck. Please advise what am I doing wrong ?

const ELEMENT_DATA: PeriodicElement[] = [
  {position: 1, name: 'Hydrogen', detail: {weight: 4.0026, symbol: 'He'}},
  {position: 2, name: 'Helium', detail: {weight: 4.0026, symbol: 'He'}},
]

displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];

Template

 <ng-container matColumnDef="weight">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> Weight </th>
    <td mat-cell *matCellDef="let element"> {{element.detail.weight}} </td>
  </ng-container>

Here is the stackblitz url for the issue
https://stackblitz.com/edit/angular-kumdeq

Upvotes: 3

Views: 5523

Answers (2)

Kona Suresh
Kona Suresh

Reputation: 1854

Yes the above code will work but we should use it where ever, we are updating the datasource (not in ngOnInit for dynamic data)

updateMatTable(customerData: Customer[]) {
    
      this.dataSource = new MatTableDataSource<Customer>(customerData);
    this.dataSource.sortingDataAccessor = (item, property) => {
      switch (property) {
        
        case 'email': return  item.address.email;
        default: return item[property];
   }
   }
    this.dataSource.paginator = this.paginator;
    this.dataSource.sort = this.sort;
  }

and call "updateMatTable" method whenever data is refreshed.

Upvotes: 0

Haijin
Haijin

Reputation: 2681

Use sortingDataAccessor, which

Allows for sort customization by overriding sortingDataAccessor, which defines how data properties are accessed.

Add this code snippet inside ngOnInit:

   this.dataSource.sortingDataAccessor = (item, property) => {
     switch (property) {
       case 'weight': return  item.detail.weight;
       case 'symbol': return  item.detail.symbol;
       default: return item[property];
  }

Link: https://stackblitz.com/edit/angular-kumdeq-z4bags

Upvotes: 10

Related Questions