Reputation: 5146
I'm implementing a mat-table that retrieve information from an API.
The mat-table is showing data as expected.
The mat-paginator is not working.
Below the code I'm using:
Component:
import {DataService} from '../../services/data.service';
import {Component, ViewChild, AfterViewInit, OnInit} from '@angular/core';
import {MatPaginator, MatTableDataSource} from '@angular/material';
@Component({
selector: 'app-projects',
templateUrl: './projects.component.html',
styleUrls: ['./projects.component.css'],
})
export class ProjectsComponent implements OnInit,AfterViewInit {
projects: any;
dataSource = new MatTableDataSource();
displayedColumns: any;
length: number;
pageSize: number=1;
pageSizeOptions = [1, 5, 10, 50];
@ViewChild(MatPaginator) paginator: MatPaginator;
constructor(private dataService: DataService) {
}
ngOnInit() {
console.log("Retrieving projects");
this.getProjects().then(
projects => {
console.log("Projects retrieved", projects);
this.projects=projects;
this.dataSource = this.projects;
console.log(this.dataSource);
this.displayedColumns = [
'prj_id',
'title',
'priority_id'
];
this.length=this.projects.length;
}
).catch(function (data){
console.log("Rejected", data);
});
}
ngAfterViewInit() {
this.dataSource.paginator = this.paginator;
}
getProjects(){
let promise = new Promise((resolve, reject) => {
this.dataService.getProjects().subscribe(
projects => {
resolve(projects);
},
error => {
console.log("error retrieving projects");
reject("error retrieving projects");
}
)
});
return promise;
}
}
export interface Projects {
prj_id: string;
title: string;
priority_id: number;
}
HTML VIEW:
<div fxLayout="column" fxLayoutAlign="center center" >
<button mat-raised-button color="primary" ><mat-icon>add</mat-icon>Project</button>
</div>
<div fxLayout="row" fxLayoutWrap="wrap">
<div fxFlex.gt-sm="100" fxFlex.gt-xs="100" fxFlex="100">
<mat-card>
<mat-card-content>
<mat-card-title backgroundColor="primary">Projects</mat-card-title>
<div class="table-rasponsive">
<mat-table #table [dataSource]="dataSource">
<!-- Position Column -->
<ng-container matColumnDef="prj_id">
<mat-header-cell *matHeaderCellDef> ID </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.prj_id}} </mat-cell>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="title">
<mat-header-cell *matHeaderCellDef> TITLE </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.title}} </mat-cell>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="priority_id">
<mat-header-cell *matHeaderCellDef> PRIORITY </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.priority_id}} </mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
<mat-paginator #paginator
[length]="length"
[pageSize]="pageSize"
[pageSizeOptions]="pageSizeOptions">
</mat-paginator>
</div>
</mat-card-content>
</mat-card>
</div>
</div>
Upvotes: 4
Views: 16420
Reputation: 418
Try this and remove code from ngAfterInit()
@ViewChild(MatPaginator) set matPaginator(mp: MatPaginator) {
this.paginator = mp;
this.dataSource.paginator = this.paginator;
}
Upvotes: 0
Reputation: 126
if you are fetching data from API, then the task is async means it will call the next steps even without completing API request, there is no data in the data source if you apply paginator without data definitely paginator won't work. if you console.log(this.paginator.paginator) you will get undefined, means your data source is not initialized, so you are not able to apply paginator to the data source
To make it work, always assign data and paginator respectively after completing API requests.
dataSource = new MatTableDataSource();
@ViewChild(MatPaginator) paginator: MatPaginator;
ngOnInit(){
yourService.getData().subscribe(
(data)=>{
this.datasource.data = data;
this.dataSource.paginator = this.paginator;
},
(error)=>{}
);
}
// note always keep <mat-paginator> after <mat-table>
Upvotes: 3
Reputation: 511
use the below line
this.dataSource = new MatTableDataSource(this.projects);
if paginator is still not working, for Dynamically loaded table data use read
argument for MatPaginator
@ViewChild(MatPaginator, {read: true}) paginator: MatPaginator;
this will do the job.
Upvotes: 4
Reputation: 1235
After having a lot of headaches I did figure out the problem. Check this line
this.dataSource = this.projects;
and change it with
this.dataSource.data = this.projects;
It should solve your problem. Also, ngAfterViewInit is ok, don't change it.
Upvotes: 9
Reputation: 554
Please try to initialize the MATPAGINATOR and MATSORT as follows and this worked for me.
public dataSource = new MatTableDataSource([]);
@ViewChild(MatSort) matSort: MatSort;
private paginator: MatPaginator;
private sort: any;
@ViewChild(MatPaginator) set matPaginator(mp: MatPaginator) {
this.paginator = mp;
this.setDataSourceAttributes();
}
@ViewChild(MatSort) set content(content: ElementRef) {
this.sort = content;
if (this.sort) {
this.dataSource.sort = this.sort;
}
}
setDataSourceAttributes() {
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
Above code checks for the paginator and sort variables and will gets set when they are undefined. Also no need to add #paginator in your HTML file.
Thanks and Regards, Kishore Kumar. K
Upvotes: 2
Reputation: 1532
Try this: Remove the code from ngAfterViewInit();
ngAfterViewInit() {
this.dataSource.paginator = this.paginator;
}
and add it in ngOnInit();
Upvotes: 1