Issue
Here’s what I’m doing:
<mat-list-item *ngFor="let company of (companies | filter:filterText | slice:lowValue:highValue ); let ix=index;" routerLink="/profile" [queryParams] ="{id: company.id, page:pageIndex}" >
<div mat-list-icon>
<img width="25" src="{{ getCompanyLogo(company.domain) }}" />
</div>
<span fxFlex="10"></span>
<a mat-line mat-line color="primary">{{ company.name }}</a>
<p mat-line></p>
<mat-divider></mat-divider>
</mat-list-item>
lowValue = pageSize*pageIndex
highValue = lowValue + pageSize
And this works.
However, the problem that I’m facing right now is after I added the filter
for filtering data from the array. When I’m on the first page which only shows 10 items, I can search using a keyword in the entire array. But soon as I hit next page, the array gets sliced and a new array with only the items to display is returned. And now, when I search for an item, all it searches for is the new sliced
array – so it may not find what I’m searching for and returns empty, even though the item exists in the original array.
What’s the best way to resolve this?
Solution
Don’t use the pipes and instead listen to the events when your filterText / pageIndex changes.
You didn’t show us much of your code, so I’ll run with some assumptions.
I assume all your records are filtered / paged localaly and the companies
is the local property holding ALL the companies. You can do something along the lines of:
// Define a new property - and assign initial value of a shallow clone of the initial array.
// Use this property in the ngFor without the pipes.
displayedRecords: Company[] = [...this.companies];
// All the other stuff you already have
...
// New method - hook it up to when filterText OR pageIndex changes
private filterRecords(): void {
// Apply filter logic from your custom pipe - below is an example.
let filtered: Company[];
if (this.filterText !== undefined && this.filterText.length > 0) {
filtered = this.companies.filter(c => c.name.toLowerCase().includes(this.filterText.toLowerCase()));
} else {
filtered = [...this.companies];
}
const lowValue = this.pageSize * this.pageIndex
const highValue = lowValue + this.pageSize
this.displayedRecords = filtered.slice(lowValue, highValue);
}