Noisemastering
Noisemastering

Reputation: 97

Material table not sorting records

I can't find what is wrong with my script, the list loads OK but when clicking on the table headers the sorting does not work.

I have tried putting the sorting part inside a TimeOut on the response and also moving it to the ngAfterViewInit() function. Everything else on my app works fine except for this.

Heres is the ts code:

import { Component, OnInit, ViewChild, ChangeDetectorRef } from '@angular/core';
import { CatalogosService } from 'src/app/services/catalogos.service';
import { MatPaginator, MatSort, MatTableDataSource, MatTableModule, MatTable, 
  MatDialog, MatDialogConfig, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
import { Response } from 'src/app/classes/response';

@Component({
  selector: 'app-lista-proveedores',
  templateUrl: './lista-proveedores.component.html',
  styleUrls: ['./lista-proveedores.component.css']
})
export class ListaProveedoresComponent implements OnInit {

  proveedores: any[];
  listData: MatTableDataSource<any>;
  displayColumns: string[]=['id','nombre','acciones'];
  searchKey: string;
  //spinner: SpinnerComponent= new SpinnerComponent;
  @ViewChild(MatSort) sort: MatSort;
  @ViewChild(MatPaginator) paginator: MatPaginator; 

  constructor(private proveedorService: CatalogosService,
              private dialog: MatDialog,
              private changeDetectorRefs: ChangeDetectorRef) { }

  ngOnInit() {
    this.getRecords();
  }

  getRecords(): void{
    this.proveedorService.getItems()
    .subscribe(
      (response: Response) => {
        //this.proveedores = response.object;
        this.listData= new MatTableDataSource(response.object);
        this.listData.sort= this.sort;
        this.listData.paginator= this.paginator;
        console.log("List data: ", this.sort);
      });
      this.changeDetectorRefs.detectChanges();
  }

}

And here is the html:

<div class="col-lg-12">
  <div class="row">
      <div class="col-lg-9 text-center">
          <h3 class="title-divider">
              <span>List</span>
          </h3>
      </div>
      <div class="col-lg-3 text-center">
          &nbsp;
      </div>
  </div>
  <div class="row">
      <div class="col-lg-12">
          <div class="mat-elevation-z8">
              <mat-table #table [dataSource]="listData" matSort>
                  <ng-container matColumnDef="id">
                      <mat-header-cell *matHeaderCellDef mat-sort-header>ID</mat-header-cell>
                      <mat-cell *matCellDef="let element">{{element.ID}}</mat-cell>
                  </ng-container>
                  <ng-container matColumnDef="nombre">
                      <mat-header-cell *matHeaderCellDef mat-sort-header>Nombre</mat-header-cell>
                      <mat-cell *matCellDef="let element">{{element.Name}}</mat-cell>
                  </ng-container>
                  <ng-container matColumnDef="acciones">
                      <mat-header-cell *matHeaderCellDef>Acciones</mat-header-cell>
                      <mat-cell *matCellDef="let row">
                          <button mat-icon-button (click)="onDetail(row)"><mat-icon>details</mat-icon></button>
                          <button mat-icon-button (click)="onEdit(row)"><mat-icon>launch</mat-icon></button>
                          <button mat-icon-button color="warn" (click)="onDelete(row)"><mat-icon>delete_outline</mat-icon></button>
                      </mat-cell>
                  </ng-container>
                  <ng-container matColumnDef="loading">
                      <mat-footer-cell *matFooterCellDef colspan="6">
                          Loading data
                      </mat-footer-cell>
                  </ng-container>
                  <ng-container matColumnDef="noData">
                      <mat-footer-cell *matFooterCellDef colspan="6">
                          No data
                      </mat-footer-cell>
                  </ng-container>
                  <mat-header-row *matHeaderRowDef="displayColumns; sticky:true "></mat-header-row>
                  <mat-row *matRowDef="let row; columns: displayColumns"></mat-row>
                  <mat-footer-row *matFooterRowDef="['loading']" [ngClass]="{'hide':listData!=null}"></mat-footer-row>
                  <mat-footer-row *matFooterRowDef="['noData']" [ngClass]="{'hide':!(listData!=null && listData.data.length==0)}"></mat-footer-row>
              </mat-table>
              <mat-paginator [pageSizeOptions]="[5, 10, 15, 25]" [pageSize]="5" showFirstLastButtons></mat-paginator>
          </div>
      </div>
  </div>

</div>

Here's also the console log displaying the MatSort object:

MatSort {_disabled: false, _isInitialized: true, _pendingSubscribers: null, initialized: Observable, sortables: Map(2), …}
direction: (...)
disableClear: (...)
disabled: (...)
initialized: Observable
_isScalar: false
_subscribe: ƒ (subscriber)
arguments: (...)
caller: (...)
length: 1
name: ""
prototype: {constructor: ƒ}
__proto__: ƒ ()
[[FunctionLocation]]: core.es5.js:474
[[Scopes]]: Scopes[4]
__proto__: Object
sortChange: EventEmitter
closed: false
hasError: false
isStopped: false
observers: (3) [Subscriber, Subscriber, Subscriber]
thrownError: null
__isAsync: false
_isScalar: false
__proto__: Subject
sortables: Map(2)
size: (...)
__proto__: Map
[[Entries]]: Array(2)
0: {"id" => MatSortHeader}
1: {"nombre" => MatSortHeader}
length: 2
start: "asc"
_direction: ""
_disabled: false
_isInitialized: true
_pendingSubscribers: null
_stateChanges: Subject {_isScalar: false, observers: Array(2), closed: false, isStopped: false, hasError: false, …}
__proto__: class_1

I've imported MatSortModule and MatTableModule on the AppModule and I have no errors displayed by the JS console.

Upvotes: 1

Views: 679

Answers (3)

Noisemastering
Noisemastering

Reputation: 97

As both comments stated, the problem was that the column names (matColumnDef) didn't match the model from the server.

Upvotes: 0

Mark B
Mark B

Reputation: 423

made a few changes to make it more like the way I do it, can you copy this in and see if it works??:

import { Component, OnInit, ViewChild, ChangeDetectorRef } from '@angular/core';
import { CatalogosService } from 'src/app/services/catalogos.service';
import { MatPaginator, MatSort, MatTableDataSource, MatTableModule, MatTable,
  MatDialog, MatDialogConfig, MatDialogRef, MAT_DIALOG_DATA } from 
'@angular/material';
import { Response } from 'src/app/classes/response';

@Component({
  selector: 'app-lista-proveedores',
  templateUrl: './lista-proveedores.component.html',
  styleUrls: ['./lista-proveedores.component.css']
})
export class ListaProveedoresComponent implements OnInit {

  proveedores: any[];
  public listData = new MatTableDataSource<any>();

  displayColumns: string[] = ['id', 'nombre', 'acciones'];
  searchKey: string;
  //spinner: SpinnerComponent= new SpinnerComponent;
  @ViewChild(MatSort) sort: MatSort;
  @ViewChild(MatPaginator) paginator: MatPaginator;

  constructor(private proveedorService: CatalogosService,
              private dialog: MatDialog,
              private changeDetectorRefs: ChangeDetectorRef) { }

  ngOnInit() {
    this.getRecords();
  }

  getRecords(): void{
    this.proveedorService.getItems()
    .subscribe(
      (response: Response) => {
        //this.proveedores = response.object;
        this.listData.data = response;
        this.listData.sort = this.sort;
        this.listData.paginator= this.paginator;
        console.log("List data: ", this.sort);
      });
      this.changeDetectorRefs.detectChanges();
  }

}

also check your uppercase is correct for the matColumnDef in your html. I think the case might not match what the object actually is. You have element.ID and matColumndef=id as an example. I just made this edit, and then saw Jesse said the same thing below. So try that first.

Upvotes: 1

Jesse
Jesse

Reputation: 2599

My understanding is that the sort headers you have defined have to match the exact property name to make sorting work. Right now you have id and ID. So just change it to:

displayColumns: string[]=['ID','nombre','acciones'];

<ng-container matColumnDef="ID">

Upvotes: 1

Related Questions