In the previous answer, the filter function will be called whenever a change is detected (basically, any event in the browser that is not associated with this component), which can be bad. A more angular and efficient way is to use the power of the Observable:
<input #search/> <div *ngIf="items$ | async as items"> <div *ngFor="let item of items">{{item.name}}</div> </div> items:any[]; items$:Observable<any>; @ViewChild('search') search:Elementref; ngOnInit() { const searchProp = 'name'; this.items$ = Observable.fromEvent(this.search.nativeElement, 'keyup').pipe( startWith(''), debounceTime(500), // let user type for half a sec distinctUntilChanged(), // don't run unless changed map(evt => this.items.filter( item => !evt.target.value || item[searchProp].toLowerCase().indexOf(evt.target.value) >-1 ) ) }
Written on a tablet from memory, if it does not work when copying, use ideological tips to find errors. :)
Thus, you can even pass the API call to the same observable, removing the need to subscribe and unsubscribe yourself, since the async channel handles all this.
Edit: to adapt this to work with 2 inputs, you can combine .fromEvent () from both, and in the filter call change the behavior according to evt.target.id. Sorry for the incomplete example, writing code on the tablet is horrible: D
RXJS merge: https://www.learnrxjs.io/operators/combination/merge.html
source share