I am trying to implement a paginator with table in angular material. The data source comes from a Node.js
server and works fine. However the paginator is like not reading the data table. I am not getting any error, but it is simply not working. Really appreciate your answers.
The Template -
<h3>Lista casos</h3>
<table mat-table [dataSource]="listaCasos" class="mat-elevation-z8">
<ng-container matColumnDef="idcaso">
<th mat-header-cell *matHeaderCellDef> ID Caso </th>
<td mat-cell *matCellDef="let caso"> {{caso.ID_CASO}} </td>
</ng-container>
<ng-container matColumnDef="estado">
<th mat-header-cell *matHeaderCellDef> Estado </th>
<td mat-cell *matCellDef="let caso"> {{caso.ESTADO_CASO}} </td>
</ng-container>
<ng-container matColumnDef="causa">
<th mat-header-cell *matHeaderCellDef> Causa </th>
<td mat-cell *matCellDef="let caso"> {{caso.CAUSA}} </td>
</ng-container>
<ng-container matColumnDef="detalles">
<th mat-header-cell *matHeaderCellDef> Detalles </th>
<td mat-cell *matCellDef="let caso">
<a routerLink="/dashboard/gestion/{{caso.ID_CASO}}"><button mat-button>Ver caso</button></a>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<mat-paginator [pageSizeOptions]="[5, 10, 20]" showFirstLastButtons></mat-paginator>
The Component -
import { Component, OnInit } from '@angular/core';
import { CasosService } from './casos.service';
import { interCaso } from '../../interfaces/interCaso';
import {AfterViewInit, ViewChild} from '@angular/core';
import {MatPaginator} from '@angular/material/paginator';
import {MatTableDataSource} from '@angular/material/table';
@Component({
selector: 'app-casos',
templateUrl: './casos.component.html',
styleUrls: ['./casos.component.css']
})
export class CasosComponent implements OnInit , AfterViewInit{
listaCasos: interCaso[] = [];
displayedColumns: string[] = ['idcaso' , 'causa' , 'estado' , 'detalles'];
dataSource = new MatTableDataSource<interCaso>(this.listaCasos);
constructor(private casosService: CasosService) { }
ngOnInit(): void {
this.getCasos();
}
@ViewChild(MatPaginator) paginator: MatPaginator;
ngAfterViewInit() {
this.dataSource.paginator = this.paginator;
}
getCasos(){
this.casosService.getCasos()
.subscribe((casos : interCaso[]) => {
this.listaCasos = casos;
console.log(casos);
})
}
}
dataSource
to listaCasos
. This will cause the table to always remain filled up will all data, because the paginator doesn't respond to the listaCasos
property, it responds to the dataSource
property. Therefore, the binding should be to the dataSource
property -<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
dataSource
with listaCasos
on declaration. But, listaCasos
will not be populated with data until ngOnInit()
gets called. So, do not initialize the dataSource
on declaration. Instead populate it inside the ngAfterViewInit()
method -// leave the dataSource uninitialized
dataSource = new MatTableDataSource<interCaso>();
//populate dataSource here
ngAfterViewInit() {
this.dataSource.data = this.listaCasos;
this.dataSource.paginator = this.paginator;
}
Edit :
Sorry I tested with static data. But, in your case the casosService
is fetching data asynchronously, and there is a chance of ngAfterViewInit()
being called while the data has not arrived yet. Therefore, it would be better if you populate the data inside the subscription to the service call -
// populate dataSource here
getCasos(){
this.casosService.getCasos()
.subscribe((casos : interCaso[]) => {
//this.listaCasos = casos;
this.dataSource.data = casos;
console.log(casos);
})
}
You'll not be needing listaCasos
anymore.