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 class="card-body">
<table class="table table-striped table-bordered table-hover">
<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 class="btn btn-primary btn-sm" (click)="viewPaymentData(paymentDetail, row)">
<i class="fa fa-eye" aria-hidden="true"></i> View
</a>
</td>
</tr>
<tr *ngIf="allPaymentList.length ==0;">
<td colspan="9" class="text-center">
<span class="align-center">No Data Found!</span>
</td>
</tr>
</tbody>
</table>
</div>
<div class="card-footer clearfix">
<div class="row">
<div class="col-md-6">
<pagination-controls
previousLabel="Prev"
nextLabel="Next"
[responsive]="true"
(pageChange)="onTableDataChange($event)"
>
</pagination-controls>
</div>
<div class="col-md-4">
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
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...