Angular Material 2 DataTable Sorting with nested objects Angular Material 2 DataTable Sorting with nested objects angular angular

Angular Material 2 DataTable Sorting with nested objects


It was hard to find documentation on this, but it is possible by using sortingDataAccessor and a switch statement. For example:

@ViewChild(MatSort) sort: MatSort;ngOnInit() {  this.dataSource = new MatTableDataSource(yourData);  this.dataSource.sortingDataAccessor = (item, property) => {    switch(property) {      case 'project.name': return item.project.name;      default: return item[property];    }  };  this.dataSource.sort = sort;}


You can write a function in component to get deeply property from object. Then use it in dataSource.sortingDataAccessor like below

getProperty = (obj, path) => (  path.split('.').reduce((o, p) => o && o[p], obj))ngOnInit() {  this.dataSource = new MatTableDataSource(yourData);  this.dataSource.sortingDataAccessor = (obj, property) => this.getProperty(obj, property);  this.dataSource.sort = sort;}columnDefs = [  {name: 'project.name', title: 'Project Name'},  {name: 'position', title: 'Position'},  {name: 'name', title: 'Name'},  {name: 'test', title: 'Test'},  {name: 'symbol', title: 'Symbol'}];

And in html

<ng-container *ngFor="let col of columnDefs" [matColumnDef]="col.name">      <mat-header-cell *matHeaderCellDef>{{ col.title }}</mat-header-cell>      <mat-cell *matCellDef="let row">        {{ getProperty(row, col.name) }}      </mat-cell>  </ng-container>


The answer as given can even be shortened, no switch required, as long as you use the dot notation for the fields.

ngOnInit() {  this.dataSource = new MatTableDataSource(yourData);  this.dataSource.sortingDataAccessor = (item, property) => {     if (property.includes('.')) return property.split('.').reduce((o,i)=>o[i], item)     return item[property];  };  this.dataSource.sort = sort;}