Reputation: 715
I am still learning JHipster by the "Full Stack Development with JHipster (Second Edition)" book which uses JHipster 6.5.0.
In Chapter 5 "Customization and Further Development" a filter functionality should be added (page 135). The authors use
a pipe provided by JHipster to filter the list using the name field of the product.
*ngFor="let product of (products | pureFilter:filter:'name'); trackBy: trackId">
With JHipster 7.0.0. I get an error telling me that "pureFilter" is an unknown pipe.
I researched and found that the pureFilter pipe seemed to be defined in ng-jhipster/pipe/pure-filter.pipe.d.ts.
But when the "ng-jhipster" package was merged with "generator-jhipster" (JHipster 7.0.0. beta release notes: https://www.jhipster.tech/2020/12/21/jhipster-release-7.0.0-beta.0.html) the pure-filter.pipe was removed by kaidohallik (GitHub issue #12909: https://github.com/jhipster/generator-jhipster/issues/12909) who stated that it was no longer in use after the "[angular] Improve logs view" (#12924).
How can I achieve the desired filtering without the pureFilter command?
Thank you very much for your support.
Upvotes: 0
Views: 457
Reputation: 73357
As I mentioned in comment, pure pipes like order by and filter perform badly, so they have been removed. You can use observables to filter your array, they work really nicely.
Here is a sample for you, including http. Apply the code to your usecase. I've used shareReplay
here to not trigger http-request for each search. shareReplay
might not work in all scenarios, for example if the list is frequently updated, but that is not taken into consideration here.
In the sample a search field is present for user to search, that is attached to a form control, and we listen to whenever the form control changes and then perform the filter, by name
property, as you have in your sample:
import { FormControl } from '@angular/forms';
import {
debounceTime,
map,
shareReplay,
startWith,
switchMap
} from 'rxjs/operators';
interface Product {
name: string;
}
// ......
searchCtrl = new FormControl();
products$ = this.searchCtrl.valueChanges.pipe(
startWith(''), // trigger initially
debounceTime(200), // just a slight debounce if user types fast
switchMap(val => { // get the data from the service and filter
return this.service.products$.pipe(
map((products: Product[]) =>
products.filter((product: Product) => {
return product.name.toLowerCase().includes(val.toLowerCase());
})
)
);
})
);
The service variable would then simply look like this:
products$ = this.http
.get<Product[]>('https://jsonplaceholder.typicode.com/users')
.pipe(shareReplay());
If you are not using http, instead remember to create an observable of your array, you can use of(put your array here)
.
In template we use the async
pipe to subscribe to the component observable products$
:
<ul>
<li *ngFor="let product of products$ | async">{{product.name}}</li>
</ul>
HERE IS A DEMO for the same
Upvotes: 2