Search code examples
angularangular-materialangular-material-table

Mat Sort header does not sort data


I have exhausted all examples, documentation and so on. I've used angular tables for three years now and even within the app I have this issue, I have other tables that have no issue working with sort. I kept comparing them but I can't figure out what the difference between the two are.

  dataSource: MatTableDataSource<IOrder>;
  @ViewChild(MatSort, { static: true }) sort: MatSort;
  @ViewChild('mainTable', { static: false }) table: MatTable<IOrder>;

then, when the data arrives from store/http call and so on:

          this.dataSource = new MatTableDataSource(orders);
          this.dataSource.sort = this.sort;
          this.ref.detectChanges();
          this.table.renderRows();

On the frontend:

<table
        matSort
        class="table"
        mat-table
        multiTemplateDataRows
        [dataSource]="dataSource"
        #mainTable
      >

and the definitions:

        <tr mat-header-row *matHeaderRowDef="activeColumns; sticky: true"></tr>
        <tr
          mat-row
          *matRowDef="let row; columns: activeColumns; let i = index"
        ></tr>

and then an example of actual row:

<ng-container matColumnDef="UPRN">
          <th
            class="table-header"
            mat-header-cell
            *matHeaderCellDef
            mat-sort-header="UPRN"
          >
            UPRN
          </th>
          <td class="table-cell" mat-cell *matCellDef="let row">
            {{ row.site.UPRN }}
          </td>
        </ng-container>

I've had one for createdAt as well which is identical.

Everything seems to be defined properly and there's no errors anywhere.

If I log on the console the mat sort, I can see all the right rows/columns in the 'Entries'.


Solution

  • What actually worked was provindg a function with a switchcase as the value for dataSource.sortingDataAccessor property, like this:

              this.dataSource.sortingDataAccessor = (item, property) => {
                switch (property) {
                  case 'UPRN':
                    return item.site.UPRN;
                  case 'Status':
                    return item.status;
    
                  case 'Updated at': {
                    return item.updatedAt;
                  }
                  case 'Updated By': {
                    return item.updatedByFriendly;
                  }
                  case 'Created by': {
                    return item.createdByFriendly;
                  }
                  default: {
                    return item[property];
                  }
                }
              };
    

    Intellisense helps out with available properties as well. The case strings must be identical to what you've provided as column definitions.