I am trying to have filterable table. I have ListComponent like this:
export class CompanyListComponent implements OnInit {
companies$: Observable<Company[]>;
private searchTerms = new Subject<string>();
constructor(private companyService: CompanyService) { }
ngOnInit() {
this.companies$ = this.searchTerms.pipe(
// wait 300ms after each keystroke before considering the term
debounceTime(300),
// ignore new term if same as previous term
distinctUntilChanged(),
// switch to new search observable each time the term changes
switchMap((term: string) => this.companyService.searchCompanies(term)),
);
}
search(term: string): void {
this.searchTerms.next(term);
}
And my html looks like that:
<input #searchBox type="text" class="form-control" id="search-box" (keyup)="search(searchBox.value)">
<table class="table">
<tr *ngFor="let company of companies$ | async">
<td>{{company.name}}</td>
</tr>
</table>
When I am writing inside the search input, table is filtered as it should be. But when I refresh page there is no data in the table at all. It appears after I put something in the input. What should I do to get all table data when the page is loaded? I tried to just start search in ngOnInit but those tries went to nowhere.
If you want the chain to be initialized when you subscribe to it you can use startWith.
this.companies$ = this.searchTerms.pipe(
debounceTime(...),
distinctUntilChanged(),
startWith(''),
switchMap(...)
);
Change searchTerms to a ReplaySubject(1) and emit a default value in the constructor.
private searchTerms = new ReplaySubject<string>(1);
constructor(private companyService: CompanyService) {
this.searchTerms.next('');
}
When the page refreshes the searchTerms does not emit a value until the user presses a key. This means that the companies$ does nothing until the first search term is emitted.
Using a replay subject allows you to set what the first value will be.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With