In Angular-14, I am implementing server-side pagination using ngx-bootstrap-pagination
with ASP.NET Core-6 as the backend.
service:
getPaymentStatus(): Observable<IPaymentStatus[]> {
return this.http.get<IPaymentStatus[]>(this.baseUrl '/payments-status');
}
I got this JSON response from the backend:
{
"data": {
"pageItems": [
{
"id": "2b0ab0db-523f-4b5f-837e-3f24ba6e0325",
"dueDate": "2025-06-12T00:00:00",
"narration": null,
"paymentStatus": 0
},
....
],
"pageSize": 10,
"currentPage": 1,
"numberOfPages": 9,
"totalRecord": 81
},
"successful": true,
"message": "All data retrieved successfully",
"statusCode": 200
}
So, in the typescipt, I got this:
component.ts:
page: number = 1;
pageSize!: number;
currentPage!: number;
numberOfPages!: number;
totalRecords!: number;
pageSizes = [10, 20, 50, 100];
ngOnInit(): void {
this.loadAllPayments();
}
getRequestParams(page: number, pageSize: number): any {
let params: any = {};
if (page) {
params[`page`] = page - 1;
}
if (pageSize) {
params[`size`] = pageSize;
}
return params;
}
handlePageChange(event: number): void {
this.page = event;
this.loadAllPayments();
}
handlePageSizeChange(event: any): void {
this.pageSize = event.target.value;
this.page = 1;
this.loadAllPayments();
}
onTableDataChange(event: any) {
this.currentPage = event;
this.loadAllPayments();
}
onTableSizeChange(event: any): void {
this.pageSize = event.target.value;
this.currentPage = 1;
this.loadAllPayments();
}
loadAllPayments() {
this.dataService.getPaymentStatus().subscribe({
next: (res: any) => {
this.allPaymentList = res.data.pageItems;
this.totalRecords = res.data.totalRecord;
this.currentPage = res.data.currentPage;
this.pageSize = res.data.pageSize;
},
error: (error) => {
this.toastr.error(error.message);
this.isLoading = false;
}
})
}
component.html:
<div >
<table >
<thead>
<tr>
<th style="width: 10px">#</th>
<th>Due Date</th>
<th>Narration</th>
<th>Payment Status</th>
<th>Action</th>
</tr>
</thead>
<tbody *ngIf="allPaymentList != undefined">
<tr *ngFor="let row of allPaymentList
| paginate : {
itemsPerPage: pageSize,
currentPage: currentPage,
totalItems: totalRecords
}; let i = index;">
<td>{{ i 1 }}.</td>
<td>{{ row?.dueDate | date: 'dd-MM-yyyy' || 'N/A' }}</td>
<td>{{ row?.narration || 'N/A' }}</td>
<td>{{ row?.paymentStatus || 'N/A' }}</td>
<td>
<a (click)="viewPaymentData(paymentDetail, row)">
<i aria-hidden="true"></i> View
</a>
</td>
</tr>
<tr *ngIf="allPaymentList.length ==0;">
<td colspan="9" >
<span >No Data Found!</span>
</td>
</tr>
</tbody>
</table>
</div>
<div >
<div >
<div >
<pagination-controls
previousLabel="Prev"
nextLabel="Next"
[responsive]="true"
(pageChange)="onTableDataChange($event)"
>
</pagination-controls>
</div>
<div >
Items Per Page:
<select (change)="onTableSizeChange($event)">
<option *ngFor="let size of pageSizes" [ngValue]="size">
{{ size }}
</option>
</select>
</div>
</div>
</div>
console.log(this.allPaymentList) gives:
{
"data": {
"pageItems": [
{
"id": "2b0ab0db-523f-4b5f-837e-3f24ba6e0325",
"dueDate": "2025-06-12T00:00:00",
"narration": null,
"paymentStatus": 0
},
{
"id": "d76b297a-70b5-4a29-82e1-937f6710cbb2",
"dueDate": "2025-03-12T00:00:00",
"narration": null,
"paymentStatus": 0
},
{
"id": "ef94ac6e-e18e-474f-961b-3b995ce7b4a7",
"dueDate": "2024-12-12T00:00:00",
"narration": null,
"paymentStatus": 0,
},
{
"id": "a4b35e3b-0bb7-4115-aee7-858259703b62",
"dueDate": "2023-03-12T00:00:00",
"narration": null,
"paymentStatus": 0
}
...
],
"pageSize": 10,
"currentPage": 1,
"numberOfPages": 9,
"totalRecord": 81,
"previousPage": 0
},
"successful": true,
"message": "All payments retrieved successfully",
"statusCode": 200
}
The pagination is as shown below:
which is correct.
But where I have an issue is that when I click on each number (1,2,3,4 ..9), it remains on the same page instead of navigating to the next page. Also, the Item Per Page is not taking me to the pages.
How do I correct all these?
Thanks
CodePudding user response:
You forgot to tell the API to return the correct data based on your pagination input format.
Here is what you can do.
in you service you need to add more information to send (this data must be provided by your backend team.
So, from this
getPaymentStatus(): Observable<IPaymentStatus[]> {
return this.http.get<IPaymentStatus[]>(this.baseUrl '/payments-status');
}
Change it to:
getPaymentStatus(page: number = 1, perPage: number = 10): Observable<IPaymentStatus[]> {
return this.http.get<IPaymentStatus[]>(this.baseUrl `/payments-status?page=${page}&perPage=${perPage}`);
}
Note: Keys page
and perPage
must be provided by your backend team.
Now, in your components you can make a request with more inputs this.dataService.getPaymentStatus($page, $perPage)
Like:
// Example One: page 1, 10 per page
this.dataService.getPaymentStatus(1).subscribe((data) => {
console.log({data});
});
// Example Two: page 2, 20 per page
this.dataService.getPaymentStatus(2, 20).subscribe((data) => {
console.log({data});
});
And so on...