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?
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();