Angular - Search filter only works for the current page in Angular Pagination Search

421 views Asked by At

In Angular-15, I am implementing search filter in my ngx-pagination with server side pagination. 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(searchQuery?: string, pageNumber?: number,pageSize?: number): Observable<IAuditList[]> {
  let params = new HttpParams()
    .set('searchQuery', searchQuery?.toString() ?? '')
    .set('pageNumber', pageNumber?.toString() ?? '')
    .set('pageSize', pageSize?.toString() ?? '');
  return this.http.get<IAuditList[]>(this.baseUrl + '/users/all-audits', { params: params });
}

component.ts:

  allAuditList: any[] = [];
  pageSize: number = 10;
  currentPage: number = 1;
  numberOfPages!: number;
  totalRecords: number = 0;
  pageSizes = [10, 20, 50, 100];
  selectedName: string = '';
  searchQuery: 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() {
  if (this.selectedName)
    this.allAuditList = this.allAuditList.filter(
      (row) =>
        row.auditType
          ?.toLowerCase()
          .includes(this.selectedName?.toLowerCase())
    );
  else
    this.allAuditList = this.allAuditList;

  this.totalRecords = this.allAuditList.length;
  this.currentPage = 1;
}

  loadAllAudits() {
    this.auditService.getAllAuditsPagination(this.searchQuery, 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.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" [value]="size">
          {{ size }}
        </option>
      </select>
    </div>
  </div>

I use text input field for search filter in the pagination.

But what I observe is that onAuditSearch() only works on the current page. For instance, If I navigate to page 2, the search filter will only work there.

How do I correct this?

1

There are 1 answers

3
Ecuros On

I think the way you sould do this with pagination is filter data on the server side and return it to your application. Right now you are only getting a part of the data you want to filter because that is how pagination is supposed to work. For example, you have a total of 50 records, but you display 10 on the first page. The remaining 40 aren't being sent by the server so your application can not filter them.

You could either request all the data from your backend (what goes againt pagination principle) or implement filtering in the backend and get your filtered data with each input (I suggest using debounce to prevent sending too much requests to the backend).