Home > Software engineering >  Angular - ngx-Pagination not working as expected
Angular - ngx-Pagination not working as expected

Time:09-18

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

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

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

  • Related