Problem:
Hi I am new to angular and I am trying to implement pagination in my api and ui both I have tested and integrated the pagination in my api but bot able to implement pagination correctly in my UI. So I am stuck when I am clicking on next page button I am not able to navigate to my previous page and on first page it shows 1/2 (dealing with a db with only 2 entries right now) but when I click on next page it shows 1/1 and the next record loads and my previous button gets disabled.
This is my html file
<mat-paginator #paginator
(page)="loadPage($event)"
[length]="length"
[pageSize]="pageSize"
[disabled]="disabled"
[showFirstLastButtons]="showFirstLastButtons"
[pageSizeOptions]="showPageSizeOptions ? pageSizeOptions : []"
[hidePageSize]="hidePageSize"
[pageIndex]="currentPage"
aria-label="Select page">
</mat-paginator>
This is my component.ts file
import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { NewPatientComponent } from 'src/app/core/dialogs/new-patient/new-patient.component';
import { PatientVisitComponent } from 'src/app/core/dialogs/patient-visit/patient-visit.component';
import { PatientService } from 'src/app/core/service/patient/patient.service';
import { AbhaRegistrationComponent } from '../abha-registration/abha-registration.component';
import { Router } from '@angular/router';
import { ActivatedRoute } from '@angular/router';
import { MatPaginator, PageEvent } from '@angular/material/paginator';
import { MatTableDataSource } from '@angular/material/table';
@Component({
selector: 'app-patient',
templateUrl: './patient.component.html',
styleUrls: ['./patient.component.css'],
})
export class PatientComponent implements AfterViewInit {
pageSize = 1;
length = 0;
pageIndex = 0;
pageSizeOptions = [5, 10, 25];
currentPage = 0;
hidePageSize = false;
showPageSizeOptions = true;
showFirstLastButtons = true;
disabled = false;
tableColumns: string[] = ['id', 'name', 'address', 'dateOfBirth', 'actions'];
selectedPatient: any;
public dataSource = new MatTableDataSource<any>([]);
@ViewChild(MatPaginator) private paginator: MatPaginator;
constructor(
private dialog: MatDialog,
private patientService: PatientService,
private router: Router,
private route: ActivatedRoute
) {}
ngAfterViewInit(): void {
this.getAllPatients();
this.dataSource.paginator = this.paginator;
}
loadPage(event: PageEvent): void {
if (event.pageIndex > this.currentPage) {
// Navigating to the next page
this.currentPage = event.pageIndex;
} else if (event.pageIndex < this.currentPage) {
// Navigating to the previous page
this.currentPage = event.pageIndex;
}
this.pageSize = event.pageSize;
this.getAllPatients();
}
getAllPatients() {
this.patientService
.getAllPatients(this.currentPage, this.pageSize)
.subscribe(
(res) => {
if (res && res.content) {
this.dataSource.data = res.content;
this.length = res.totalElements;
} else {
console.error('API response is missing expected data:', res);
}
},
(err) => {
console.error('Error getting patients:', err);
}
);
}
newPatientDialog() {
this.dialog.open(NewPatientComponent).afterClosed().subscribe((res) => {
this.getAllPatients();
});
}
openVisitDialog(patient: any) {
this.dialog.open(PatientVisitComponent, {
data: patient,
});
}
openAbhaDialog(patient: any) {
this.router.navigateByUrl('/abha', { state: patient });
}
applyFilter(event: Event) {
const filterValue = (event.target as HTMLInputElement).value.trim().toLowerCase();
this.dataSource.filter = filterValue;
this.dataSource.filterPredicate = this.customFilterPredicate();
}
customFilterPredicate() {
return (data: any, filter: string) => {
const name = `${data.firstName} `.toLowerCase();
return name.includes(filter);
};
}
}
Solution:
Hard to say, what goes wrong without knowing backend side. But maybe I can give you a hint, that may solve your problem.
When switching pages you call loadPage()
and in there you call getAllPatients()
. There you are setting this.length = res.totalElements;
. Are you sure that your API response for totalElements is NOT 1 on your second page? I suppose this would result in only having one page left on your paginator.
Offtopic:
In loadPage() instead of
if (event.pageIndex > this.currentPage) {
// Navigating to the next page
this.currentPage = event.pageIndex;
} else if (event.pageIndex < this.currentPage) {
// Navigating to the previous page
this.currentPage = event.pageIndex;
}
you can just write this.currentPage = event.pageIndex;
. The if/else statement is senseless here.