I have tried all the things I know but with no success. I want to add pagination to a covid-19 table. The paginator shows how much rows are in the table but it is not splitting them into pages.
Here is the code I've done.
Here is my component.ts
:
import { AfterViewInit, Component, HostListener, OnInit, ViewChild, } from '@angular/core';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTable } from '@angular/material/table';
import { merge } from 'rxjs';
import { tap } from 'rxjs/operators';
import { Countries, sortData } from '../app.model';
import { AppService } from '../app.service';
import { DataTableDataSource } from './data-table-datasource';
import { animate, state, style, transition, trigger, } from '@angular/animations';
@Component({
selector: 'app-data-table',
templateUrl: './data-table.component.html',
styleUrls: ['./data-table.component.css'],
animations: [
trigger('detailExpand', [
state('collapsed', style({ height: '0px', minHeight: '0' })),
state('expanded', style({ height: '*' })),
transition(
'expanded <=> collapsed',
animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')
),
]),
],
})
export class DataTableComponent implements AfterViewInit {
@ViewChild(MatPaginator, { static: true }) paginator!: MatPaginator;
@ViewChild(MatSort) sort!: MatSort;
@ViewChild(MatTable) table!: MatTable<Countries>;
@ViewChild('paginator', { read: MatPaginator }) paginatorlist: MatPaginator;
dataSource: DataTableDataSource;
filter: sortData = new sortData();
/** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
displayedColumns = [];
scrWidth: any;
constructor(public appService: AppService) { }
ngOnInit() {
this.dataSource = new DataTableDataSource(this.appService);
this.sortData(false);
this.setupTable();
this.getScreenSize();
}
sortData(isChange: boolean) {
if (isChange) {
this.filter.pageSize = this.paginator.pageSize;
this.filter.pageNumber = this.paginator.pageIndex + 1;
// this.filter.sortColumn = this.sort.active;
// this.filter.sortDirection = this.sort.direction;
console.log(this.paginator.pageIndex);
} else {
this.filter.pageSize = 15;
this.filter.pageNumber = 1;
// this.filter.sortColumn = 'todayCases';
// this.filter.sortDirection = 'true';
// console.log(this.filter);
}
this.dataSource.loadData(this.filter);
(error) => console.error(error);
}
ngAfterViewInit() {
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
}
Here is my datasource.ts
:
import { DataSource } from '@angular/cdk/collections';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { finalize, map } from 'rxjs/operators';
import { Observable, of as observableOf, merge, BehaviorSubject } from 'rxjs';
import { ApiResponse, Countries, sortData } from '../app.model';
import { AppService } from '../app.service';
export class DataTableDataSource extends DataSource<Countries> {
public dataSubject = new BehaviorSubject<Countries[]>([]);
private loadingSubject = new BehaviorSubject<boolean>(false);
public loading$ = this.loadingSubject.asObservable();
private totalDataCountSubject = new BehaviorSubject<number>(0);
public totalDataCount$ = this.totalDataCountSubject.asObservable();
paginator: MatPaginator;
sort: MatSort;
constructor(private appService: AppService) {
super();
}
loadData(filter: sortData) {
this.appService
.getData(filter)
.pipe(finalize(() => this.loadingSubject.next(false)))
.subscribe((data: any) => {
// console.log(data.response);
if (data) {
this.totalDataCountSubject.next(data.length);
this.dataSubject.next(data);
console.log(data.length);
}
});
}
connect(): Observable<Countries[]> {
return this.dataSubject.asObservable();
}
disconnect(): void {
this.dataSubject.complete();
this.totalDataCountSubject.complete();
this.loadingSubject.complete();
}
}
And here is my HTML
:
<div class="mat-elevation-z8 data-table">
<table mat-table multiTemplateDataRows class="full-width-table" matSort matSortActive="todayCases" matSortDirection="asc"
aria-label="Elements" [dataSource]="dataSource">
<!-- Country Column -->
<ng-container matColumnDef="country">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Country</th>
<td mat-cell *matCellDef="let row">{{ row.country }}</td>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="cases">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Cases</th>
<td mat-cell *matCellDef="let row">{{ row.cases }}</td>
</ng-container>
<!-- Id Column -->
<ng-container matColumnDef="active">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Active</th>
<td mat-cell *matCellDef="let row">{{ row.active }}</td>
</ng-container>
<!-- Id Column -->
<ng-container matColumnDef="todayCases">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Today Cases</th>
<td mat-cell *matCellDef="let row">{{ row.todayCases }}</td>
</ng-container>
<!-- Id Column -->
<ng-container matColumnDef="todayDeaths">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Total Deaths</th>
<td mat-cell *matCellDef="let row">{{ row.todayDeaths }}</td>
</ng-container>
<!-- Id Column -->
<ng-container class="recovered" matColumnDef="recovered">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Recovered</th>
<td mat-cell *matCellDef="let row">{{ row.recovered }}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
</table>
<mat-paginator #paginator [length]="dataSource.totalDataCount$ | async" [pageSize]="15" [pageSizeOptions]="[15, 20, 25]">
</mat-paginator>
</div>
Thanks in advance
The issue is you have to set the total available data length to the pageSize
parameter of the paginator
.
For example, you have 30 countries' data and your pageSize
is 10. So, you have to set the pageSize
parameter of the paginator
to 30 and your visible data will be 10.
I've mocked your AppService
with static data. And showed how to populate data for pagination.
And you also missed filtering data after change of pageSize
or page
. I've also done that.
Observe the demo and you'll be able to understand.
Working solution created at Stackblitz