Reputation: 97
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">
</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
Reputation: 97
As both comments stated, the problem was that the column names (matColumnDef) didn't match the model from the server.
Upvotes: 0
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
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