Search code examples
angularangular-material-5

Sorting Not Working Angular Material Design Table


Using an Angular Material Design table, I'm simply trying to sort the headers of two columns in a data table. (They are the Employee Name and Job Title columns in the code below.) Both aren't sorting. Not sure why. Here's my code and thanks, CM

employee-table.component.html

<div>

  <mat-table [dataSource] = "dataSource" matSort>
    <ng-container matColumnDef="photo">
      <mat-header-cell *matHeaderCellDef>Profile</mat-header-cell>
      <mat-cell *matCellDef="let employee"><img width = "100" height = "100" src = "../assets/images/{{employee.username}}.jpg" >
      </mat-cell>
    </ng-container>

    <ng-container matColumnDef="name">
      <mat-header-cell *matHeaderCellDef mat-sort-header>Employee Name</mat-header-cell>
      <mat-cell *matCellDef="let employee">{{employee.name}}</mat-cell>
    </ng-container>


    <ng-container matColumnDef="position">
      <mat-header-cell *matHeaderCellDef mat-sort-header>Job Title</mat-header-cell>
      <mat-cell *matCellDef="let employee">{{employee.position}}</mat-cell>
    </ng-container>

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

  </mat-table>
</div>

employee-table.component.ts

import { Component, OnInit, ViewChild } from '@angular/core';
import {Observable} from 'rxjs/Observable';
import {MatSort, MatSortable, MatTableDataSource} from '@angular/material';
import {EmployeeService} from '../employee.service';

@Component({
  selector: 'app-employee-table',
  templateUrl: './employee-table.component.html',
  styleUrls: ['./employee-table.component.css']
})
export class EmployeeTableComponent implements OnInit {
  @ViewChild(MatSort) sort: MatSort;
  dataSource;
  displayedColumns = ['photo', 'name', 'position'];

  constructor() { }
  ngOnInit() {   
    this.dataSource =[
            {
              "id": 1,
              "name": "Leanne Grahamz",
              "username": "Bret",
              "position": "Software Developer"
            },
            {
              "id": 2,
              "name": "Ervin Howell",
              "username": "Antonette",
              "position": "Graphic Designer"
            },
            {
              "id": 3,
              "name": "Clementine Bauch",
              "username": "Samantha",
              "position": "Front End Developer"
            },
            {
              "id": 4,
              "name": "Patricia Lebsack",
              "username": "Karianne",
              "position": "Full Stack Developer"
            },
            {
              "id": 5,
              "name": "Chelsey Dietrich",
              "username": "Kamren",
              "position": "Database Administrator" 
            }
    ]; //End data object

    this.dataSource.sort = this.sort;

  }//End ng onInit

}//End class EmployeeTableComponent

Solution

  • You are setting the datasource sort this.dataSource.sort = this.sort; too early in the lifecycle. As suggested by the material.angular.io examples, you should set the datasource sort after the view init :

    Copied from the material.angular.io example :

     /**
       * Set the sort after the view init since this component will
       * be able to query its view for the initialized sort.
       */
      ngAfterViewInit() {
        this.dataSource.sort = this.sort;
      }
    

    You should also edit your datasource initialisation :

    ngOnInit() {
     this.dataSource = new MatTableDataSource([{
         "id": 1,
         "name": "Leanne Grahamz",
         "username": "Bret",
         "position": "Software Developer"
        }, 
        ...
        {
         "id": 5,
         "name": "Chelsey Dietrich",
         "username": "Kamren",
         "position": "Database Administrator"
        }
       ]);
    }
    

    Here is an edit of the initial example with your code.