Search code examples
angulartypescriptsortingangular-materialangular-material-table

Angular Material - Sort the data for mat-table


I am using Angular Material. How can I sort the data?

HTML file

<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">


    <ng-container matColumnDef="position">
        <mat-header-cell *matHeaderCellDef mat-sort-header> No. </mat-header-cell>
        <mat-cell *matCellDef="let element"> {{element.assetId}} </mat-cell>
    </ng-container>


    <ng-container matColumnDef="name">
        <th mat-header-cell *matHeaderCellDef mat-sort-header> Name </th>
        <td mat-cell *matCellDef="let element"> {{element.assetName}} </td>
    </ng-container>


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


    <ng-container matColumnDef="symbol">
        <th mat-header-cell *matHeaderCellDef mat-sort-header> Symbol </th>
        <td mat-cell *matCellDef="let element"> {{element.hddName}} </td>
    </ng-container>

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

.ts file

import { Component, OnInit, ViewChild } from '@angular/core';
import {MatPaginator} from '@angular/material/paginator';
import {MatTableDataSource} from '@angular/material/table';
import {MatSort} from '@angular/material/sort';
import { AddAssetService } from '../shared/add-asset.service';
export interface Element {
  assetId: any;
  assetName: any;
  cpuName: any;
  hddName:  any;
}

@Component({
  selector: 'app-material-two',
  templateUrl: './material-two.component.html',
  styleUrls: ['./material-two.component.css']
})
export class MaterialTwoComponent implements OnInit {
  displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];
  dataSource:any;
  @ViewChild(MatSort, { static: false }) sort!: MatSort;
  constructor(private service:AddAssetService) { }

  ngOnInit(): void {

   this.assetGrid();
   this.ngAfterViewInit()
    console.log(this.dataSource);
  }
  assetGrid() {
    this.service.GetAssets().subscribe(user=>{
      this.dataSource = new MatTableDataSource<Element>(user);
       console.log("this.listData",this.dataSource);
       console.log("this.user",user)
    });
  }
    ngAfterViewInit() {
      this.dataSource.sort = this.sort;
  }

}

Getting the error:

core.js:6210 ERROR TypeError: Cannot set property 'sort' of undefined.


Solution

  • You can avoid this error

    core.js:6210 ERROR TypeError: Cannot set property 'sort' of undefined.

    by checking this.dataSource must not be undefined nor null first before assigning as below:

    .component.ts

    if (this.dataSource) {
      this.dataSource.sort = this.sort;
    }
    

    Concerns

    Concern 1: Missing implements AfterViewInit

    You must implement AfterViewInit on your component. Otherwise, ngAfterViewInit will not be executed. And remove calling this.ngAfterViewInit method from ngOnInit method.

    .component.ts

    import { AfterViewInit } from '@angular/core';
    
    export class MaterialTwoComponent implements OnInit, AfterViewInit {
      ngOnInit(): void {
        this.assetGrid();
        console.log(this.dataSource);
      }
    
      ...
    }
    

    Concern 2: matColumnDef must be exact with property name

    matColumnDef must be the same as the data's property name. If not, the sorting will not works. Hence, you also need to update displayedColumns for the properties.

    .component.html

    <ng-container matColumnDef="assetId">
      ...
    </ng-container>
    
    <ng-container matColumnDef="assetName">
      ...
    </ng-container>
    
    <ng-container matColumnDef="cpuName">
      ...
    </ng-container>
    
    <ng-container matColumnDef="hddName">
      ...
    </ng-container>
    

    .component.ts

    displayedColumns: string[] = ['assetId', 'assetName', 'cpuName', 'hddName'];
    

    Sample Solution on StackBlitz


    References

    Angular Material Table Sorting