Marcos Arroyo
Marcos Arroyo

Reputation: 55

Angular 8 Material Sort not working in Datatable (MatTable)

I have a simple Datatable from Angular Material which I want to be able to sort using Material Sort.

I've tried everything: setting the sort in the ngOnInit just after the dataSource is set; passing values directly in the dataSource for, I don't know, faster initialization?; in the HTML code using tags like , and those like in the Angular Material documentation examples, but it's the same; I tried not using the Classes part to avoid possible errors due to it being a nested object, etc.

HTML

[...]

<mat-table [dataSource]="dataSource" matSort>

    <!-- ID Column -->
    <ng-container matColumnDef="pkMaterialid">
    <mat-header-cell *matHeaderCellDef mat-sort-header> ID </mat-header-cell>
    <mat-cell *matCellDef="let element"> {{element.pkMaterialid}} </mat-cell>
    </ng-container>

    <!-- Desc Column -->
    <ng-container matColumnDef="materialdesc">
    <mat-header-cell *matHeaderCellDef mat-sort-header> Description </mat-header-cell>
    <mat-cell *matCellDef="let element"> {{element.materialdesc}} </mat-cell>
    </ng-container>

    <!-- Class Column -->
    <ng-container matColumnDef="materialClasses">
    <mat-header-cell *matHeaderCellDef mat-sort-header> Class </mat-header-cell>
    <mat-cell *matCellDef="let element"> 
        <span *ngFor="let class of element.materialClasses; let i = index">
        <span *ngIf="i > 0">, </span>
        {{class.pkMatclassid}}
        </span> 
    </mat-cell>
    </ng-container>

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

TypeScript

import { Component, OnInit, OnDestroy, ViewChild, ElementRef, AfterViewInit } from '@angular/core';
import { MatAutocomplete, MatAutocompleteSelectedEvent, MatTableDataSource, MatSort } from '@angular/material';

// These interfaces are actually classes in separated scripts of my code, I created these for demostration purposes
interface Material {
  pkMaterialid: string, 
  materialdesc: string,
  materialClasses: MaterialClass[]
}

interface MaterialClass {
  pkMatclassid: string,
  matclassdesc: string,
}

@Component({
  selector: 'app-material-definitions',
  templateUrl: './material-definitions.component.html',
  styleUrls: ['./material-definitions.component.scss']
})
export class MaterialDefinitionsComponent implements OnInit, AfterViewInit {

  matList: Material[] = [];

    //Random values
  classList: MaterialClass[] = [
    { pkMatclassid: 'C1', matclassdesc: 'Class1' },
    { pkMatclassid: 'C1', matclassdesc: 'Class1' },
    { pkMatclassid: 'C1', matclassdesc: 'Class1' },
  ];

  displayedColumns: string[] = ['pkMaterialid', 'materialdesc', 'materialClasses'];
  @ViewChild(MatSort, {static: true}) sort: MatSort;
  dataSource: MatTableDataSource<Material>;

ngOnInit() {

    // Here I create some random Materials for testing
    for(let i=0; i<10; i++){
      let mat: Material = {
        pkMaterialid: 'ID' + i,
        materialdesc: 'Desc' + i,
        materialClasses: [this.classList[Math.floor(i%3)]];

      this.matList.push(mat);
    }

    this.dataSource =  new MatTableDataSource(this.matList);

  }

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

  //Other stuff
  [...]

}


updated package.json:


"dependencies": {
    "@angular/animations": "~8.1.1",
    "@angular/cdk": "^8.0.2",
    "@angular/common": "^8.1.1",
    "@angular/compiler": "~8.1.1",
    "@angular/core": "^8.1.1",
    "@angular/forms": "~8.1.1",
    "@angular/material": "^8.0.2",
    "@angular/platform-browser": "~8.1.1",
    "@angular/platform-browser-dynamic": "~8.1.1",
    "@angular/router": "^8.1.1",
    "@ngrx/effects": "^8.0.1",
    "@ngrx/store": "^8.0.1",
    "angular-bootstrap-md": "^7.5.4",
    "bootstrap": "^4.3.1",
    "core-js": "^2.5.4",
    "hammerjs": "^2.0.8",
    "ngx-image-compress": "^7.2.4",
    "rxjs": "^6.5.2",
    "ts-md5": "^1.2.4",
    "tslib": "^1.9.0",
    "zone.js": "~0.9.1"
  },

I don't get any kind of error messages, it just doesn't do anything (I see the sort arrows when I click the headers, but nothing happens). Hope you can help me. Thank you all beforehand!

Upvotes: 0

Views: 2235

Answers (2)

R_upture
R_upture

Reputation: 11

Maybe its late to answer, but I encountered this issue recently. You can fix this by replacing {static: true} with null as:

  displayedColumns: string[] = ['pkMaterialid', 'materialdesc', 'materialClasses'];
  @ViewChild(MatSort, null) sort: MatSort;

Upvotes: 0

yashpatelyk
yashpatelyk

Reputation: 429

Just import MatSortModule in your module and it will work,

import {MatSortModule} from '@angular/material/sort';

...
declarations : [...]
imports : [MatSortModule, ...],
...

Upvotes: 1

Related Questions