Search code examples
angularngx-pagination

Search filter does not correspond with pagination in ngx-pagination


I am implementing ngx-pagination with server side pagination in ASP.NET Core-6 Web API. Precisely, I have a search text input. I have this code:

JSON Response:

{
      "data": {
        "pageItems": [
          {
            "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
            "auditType": "string",
            "actionPerformed": "string",
            "actionPerformedTime": "2022-10-28T05:54:12.830Z"
          }
        ],
        "currentPage": 1,
        "pageSize": 10,
        "numberOfPages": 3,
        "totalRecord": 33
      },
      "successful": true,
      "message": "string",
      "statusCode": 0
}

model:

export interface IPageItem {
  id: string;
  auditType: string;
  actionPerformed: string;
  actionPerformedTime: Date;
}

export interface IData {
  pageItems: IPageItem[];
  pageSize: number;
  currentPage: number;
  numberOfPages: number;
  totalRecord: number;
}

export interface IAuditList {
  data: IData;
  successful: boolean;
  message: string;
  statusCode: number;
}

service:

getAllAuditsPagination(pageNumber?: number,pageSize?: number): Observable<IAuditList[]> {
  return this.http.get<IAuditList[]>(this.baseUrl + '/users/all-audits?pagenumber='+ pageNumber+'&pageSize='+pageSize);
}

component.ts:

  allAuditList: any[] = [];
  dataBk: IPageItem[] = this.allAuditList;
  pageSize: number = 10;
  currentPage: number = 1;
  numberOfPages!: number;
  totalRecords: number = 0;
  pageSizes = [10, 20, 50, 100];
  selectedName: string = '';

  handlePageChange(event: number): void {
    this.currentPage = event;
    this.loadAllAudits();
  }

  handlePageSizeChange(event: any): void {
    this.pageSize = event.target.value;
    this.currentPage = 1;
    this.loadAllAudits();
  }

  onAuditSearch() {
    this.allAuditList = this.dataBk.filter(
      (row) =>
        row.auditType
          ?.toLowerCase()
          .includes(this.selectedName?.toLowerCase())
    );
  }

  loadAllAudits() {
    this.auditService.getAllAuditsPagination(this.currentPage, this.pageSize).subscribe({
      next: (res: any) => {
        this.allAuditList = res.data.pageItems;
        this.totalRecords = res.data.totalRecord;
        this.currentPage = res.data.currentPage;
        this.pageSize = res.data.pageSize;
        this.dataBk = res.data.pageItems;
        this.isLoading = false;
      }
    })
  }

component.html:

<div class="row">
    <div class="col-sm-6 col-xs-6 col-6">
      <div class="form-group">
        <label for="auditType">Audit Type:</label>
        <input
          type="text"
          autocomplete="off"
          class="form-control"
          id="auditType"
          [(ngModel)]="selectedName"
          (input)="onAuditSearch()"
          placeholder="auditType"
        />
      </div>
    </div>
</div>

  <tr
    *ngFor="
      let row of allAuditList
        | paginate
          : {
              itemsPerPage: pageSize,
              currentPage: currentPage,
              totalItems: totalRecords
            }
        | orderBy : order : reverse : caseInsensitive;
      let i = index
    "
  >

  <div class="row">
    <div class="col-md-6">
      <pagination-controls
      previousLabel="Prev"
      nextLabel="Next"
      [responsive]="true"
      (pageChange)="handlePageChange($event)"
    >
    </pagination-controls>
    </div>
    <div class="col-md-4">
      Items Per Page:
      <select (change)="handlePageSizeChange($event)">
        <option *ngFor="let size of pageSizes" [ngValue]="size">
          {{ size }}
        </option>
      </select>
    </div>
  </div>

In the component.html, when user types in the text input field for search in auditType ([(ngModel)]="selectedName"), the the items in the page changes (this is working), but the pagination (1,2,3,...6) remains the same.

How do I correct this?

image1

image2


Solution

  • The problem is when you perform the filtering operation, you should also update the info for the ngx-pagination element such as totalRecords, currentPage, etc.

    onAuditSearch() {
      if (this.selectedName)
        this.allAuditList = this.dataBk.filter(
          (row) =>
            row.auditType
              ?.toLowerCase()
              .includes(this.selectedName?.toLowerCase())
        );
      else
        this.allAuditList = this.dataBk;
    
      this.totalRecords = this.allAuditList.length;
      this.currentPage = 1;
    }
    

    But note that when you perform a change on page number or page size, the server-side API will be loaded due to this line:

    this.loadAllAudits()
    

    You have to modify the handling for both handlePageChange and handlePageSizeChange in case the text field is filled and does not require performing server-size pagination. Example:

    if (!this.selectedName)
      this.loadAllAudits();