import { Component, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms';
import { Observable, fromEvent, of, Subject, merge, combineLatest } from 'rxjs';
import { map, startWith, switchMap, tap, debounceTime, filter, scan, withLatestFrom, mergeMap, takeUntil, takeWhile, distinctUntilChanged, skipUntil, exhaustMap, endWith } from 'rxjs/operators';
import { MatAutocomplete } from '@angular/material/autocomplete';
import { takeWhileInclusive } from 'rxjs-take-while-inclusive';
export interface ILookup {
id: number,
name: string
}
@Component({
selector: 'autocomplete-filter-example',
templateUrl: 'autocomplete-filter-example.html',
styleUrls: ['autocomplete-filter-example.scss'],
})
export class AutocompleteFilterExample implements OnInit {
searchText = new FormControl({ id: 2, name: 'ana' });
filteredLookups$: Observable<ILookup[]>;
private lookups: ILookup[] = [];
private nextPage$ = new Subject();
private _onDestroy = new Subject();
private getProducts(startsWith: string, page: number): Observable<ILookup[]> {
console.log(`api call filter: ${startsWith}`);
const take = 10;
const skip = page > 0 ? (page - 1) * take : 0;
const filtered = this.lookups
.filter(option => option.name.toLowerCase().startsWith(startsWith.toLowerCase()))
console.log(`skip: ${skip}, take: ${take}`);
return of(filtered.slice(skip, skip + take));
}
ngOnInit() {
this.lookups = [{ id: 1994, name: 'ana' }, { id: 1989, name: 'narcis' }]
for (let i = 1; i < 100; i++) {
this.lookups.push({ id: i, name: 'test' + i })
}
const filter$ = this.searchText.valueChanges.pipe(
startWith(''),
debounceTime(200),
filter(q => typeof q === "string"));
this.filteredLookups$ = filter$.pipe(
switchMap(filter => {
let currentPage = 1;
return this.nextPage$.pipe(
startWith(currentPage),
exhaustMap(_ => this.getProducts(filter, currentPage)),
tap(() => currentPage++),
takeWhileInclusive(p => p.length > 0),
scan((allProducts, newProducts) => allProducts.concat(newProducts), []),
);
}));
}
displayWith(lookup) {
return lookup ? lookup.name : null;
}
onScroll() {
this.nextPage$.next();
}
ngOnDestroy() {
this._onDestroy.next();
this._onDestroy.complete();
}
}