0

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>&nbsp;
              </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:

pagination

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

1 Answer 1

0

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...

Sign up to request clarification or add additional context in comments.

3 Comments

That has already been taken care of from the backend. See console.log(this.allPaymentList) towards the end of my submitted and updated code. It displays totalPages and perPage. But the issue as I stated is that clicking on each number (1,2,3, ...9) is not going to its page and also ItemPerPage is not responding. That's why I put the screenshot
I know, but you are only changing the local variables, when you press on page 2, the local variable will change, that's true, and you will fetch the same data for page 1. But, If you provided a query params in the URL when making a request, It will tell the API which page you want to retrieve.
Is currentPage in the API JSON response not the same as $page that you gave. Secondly, can you repoduce the solution in stackblitz. .Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.