1

I'm building a web app using angular material and am trying to display a table with sorting. The sorting works on all but this column. This is the only column where the type of the variable isn't a string or a number.

I've already try'd change column def to office.name etc, but to no avail.

<ng-container matColumnDef="office">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> Office </th>
    <td mat-cell *matCellDef="let row">{{ row.office.name }}</td>
</ng-container>

Component Code:

export class DataTableComponent implements OnInit, OnChanges {
  dataTableColumns: string[] = ['name', 'emailAddress', 'office', 'active'];
  dataSource: MatTableDataSource<Data>;
  data: Data[];
  offices: Office[];
  value: string;
  oldFilterValue: string;

  @ViewChild(MatPaginator) paginator: MatPaginator;
  @ViewChild(MatSort) sort: MatSort;
  @ViewChild(ContextMenuComponent) public basicMenu: ContextMenuComponent;
  @ViewChild(MatTable) table: MatTable<any>;
  @ViewChild(MatMenuTrigger)
  contextMenu: MatMenuTrigger;

  contextMenuPosition = { x: '0px', y: '0px' };

  constructor(
    private dataService: DataService,
    public dialog: MatDialog,
    private officeService: OfficeService,
    public snackBar: MatSnackBar) {
  }

  ngOnInit() {
    this.getData();
    this.getOffices();
  }

  ngOnChanges(changes: SimpleChanges): void {
    this.updateTable();
  }

  getData(): void {
    this.dataService.get().subscribe((res) => {
      setTimeout(() => {
      this.data= res as any[];
      this.updateTable();
    });
  }

  updateTable(): void {
    this.dataSource = new MatTableDataSource(this.data);
    this.dataSource.paginator = this.paginator;
    this.dataSource.sort = this.sort;
    if (this.value) {
      this.applyFilter(this.value);
    }
  }

  getOffices(): void {
    this.officeService.getOffices().subscribe((res) => {
      this.offices = res;
    });
  }

  applyFilter(filterValue: string) {
    this.dataSource.filter = filterValue.trim().toLowerCase();
    if (this.dataSource.paginator) {
      this.dataSource.paginator.firstPage();
    }
  }
3
  • by default the angular material worked on root level keys value and you trying to sort on nested value row.office.name that's why it not work. follow the document: material.angular.io/components/table/overview#sorting Commented May 16, 2019 at 9:09
  • Yes I guess that's why it wasn't working, I was looking for a solution to this Commented May 16, 2019 at 9:12
  • check this example of sorting on nested object key working demo stackblitz.com/edit/angular-ef8lwu hope this will help to get out of this. Commented May 16, 2019 at 9:31

1 Answer 1

1

You can use sortingDataAccessor on your data source to sort the object in your table.

Assuming that your data source name is dataSrouce

@ViewChild(MatSort) sort: MatSort;


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

And in your HTML, change matColumnDef="office" to matColumnDef="office.name"

<ng-container matColumnDef="office.name">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> Office </th>
    <td mat-cell *matCellDef="let row">{{ row.office.name }}</td>
</ng-container>
Sign up to request clarification or add additional context in comments.

6 Comments

I tried to just copy and paste this into my ngOnInit() method, but didn't seem to make a difference, am I supposed to change the html or put it in a different method?
After this.dataSource.paginator = this.paginator;
unfortunately the updated one doesn't work either :(
Try to change your HTML, you need to set office.name instead of office. I've updated my answer. Does it help?
Got it working but had to set it up in the getData method bit, bit unsual. Thanks for all the help, bit of code duplication but it still works :)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.