Reputation: 63
searchFunction is being called when a user enters value in autocomplete textbox. So, what this code should do is return the oprions to the autocomplete dropdown on the basis of user input and it should only show the options of the last query.
If I use this code and when it called in other place is does not return anything(when I use subject and observable like above). The place where this function is called expect a observable, so we have to return and observable from here. Also, I cannot edit/chnage the function which is calling the above function.
To get only the last results I need switchMap. Is there anyother way to do same?
Below code is not working. Pleas suggest want needs to be changed
export class AppComponent {
readonly search = new ReplaySubject<string>(1);
searchResponse!: Observable<string[]>;
constructor(private http: HttpClient) {}
searchFunction = (query: string) => {
return (this.searchResponse = this.search.pipe(
debounceTime(300),
distinctUntilChanged(),
switchMap((query: string) => {
return this.http.searchData(query).pipe(
map((res: string[]) => {
return res.slice(0, 100);
})
);
})
));
};
}
Upvotes: 1
Views: 2780
Reputation: 7331
The problem is with this:
searchFunction is being called when a user enters value in autocomplete textbox
You create a new subcription each time you call the function. While the template should unsubscribe from the previous subscription, the solution is not ideal.
I would try something like this:
export class AppComponent {
readonly search = new Subject<string>();
readonly searchResponse: Observable<string[]>;
constructor(private http: HttpClient) {
this.searchResponse = this.search.pipe(
debounceTime(300),
distinctUntilChanged(),
switchMap((query: string) => {
return this.http.searchData(query).pipe(
map((res: string[]) => {
return res.slice(0, 100);
}),
// So we don't wreck the pipe. Import EMPTY from 'rxjs'
catchError(() => EMPTY)
);
})
}
searchFunction = (query: string) => {
this.search.next(query);
};
}
In that case you have single subscription to the search term. If you're using reactive forms you could listen to valueChanges
.
Upvotes: 2
Reputation: 1138
In this article you can find a complete implementation with RxJS operators - see section "Search TypeAhead - switchMap Operator Example" - hope it helps!
https://blog.angular-university.io/rxjs-higher-order-mapping/
Upvotes: 0