In Angular tutorial Get data from server (https://angular.io/tutorial/toh-pt6), there is a code snippet which handles the search, and making a http call to get the heroes with the search term.
import { Component, OnInit } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators';
import { Hero } from '../hero';
import { HeroService } from '../hero.service';
@Component({
selector: 'app-hero-search',
templateUrl: './hero-search.component.html',
styleUrls: [ './hero-search.component.css' ]
})
export class HeroSearchComponent implements OnInit {
heroes$!: Observable<Hero[]>;
private searchTerms = new Subject<string>();
constructor(private heroService: HeroService) {}
// Push a search term into the observable stream.
search(term: string): void {
this.searchTerms.next(term);
}
ngOnInit(): void {
this.heroes$ = 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.heroService.searchHeroes(term)),
);
}
}
Let say I add another button to sort heroes by name, and it is handled by sort
method
sort(order: 'asc' | 'desc') {
this.sortingOrder$.next(order);
}
Take two different cases
Case 1: When the sort is click, fetch the heroes with both current searchTerm and sortOrder this.heroService.searchHeroes(term, sortOrder)
and apply it to heroes$
stream.
Case 2: When the sort is click, empty the searchTerm and only fetch heroes by sortOrder e.g. this.heroService.searchHeroes('', sortOrder)
and apply it to heroes$
stream. Meaning in this case the sort button and the search work independently.
How should I implement to update the heroes$
stream for those cases?
You can achieve this by using the combineLatest
operator and adding the two observables to create your stream. It takes in an array of observable sources and once all sources have emitted at least once, an array of the mapped values are available for consumption. Please note that combineLatest
will only emit once both sources have emitted at least one value. A BehaviorSubject
is often helpful here since it emits a value when created as apposed to a Subject
.