Currently, I'm working on integrating a search box feature that needs to trigger an API call when the user enters a value. The goal is to initiate the call after the user stops typing for a certain amount of time.
The initial request setup is functioning correctly:
this.searchForm.get('searchQuery').valueChanges.pipe(
filter(data => data.trim().length > 0),
debounceTime(500),
switchMap( (query: string) => this.productsService.searchProducts(query))
).subscribe();
However, during continuous typing, the system seems to be waiting for another 500ms and then sending multiple requests (equivalent to the number of characters typed).
productsChanged = new Subject<Product[]>();
searchProducts(query: string) {
return this.http.get<Product[]>(this.baseUrl + '/products/search/' + query)
.pipe(
tap(products => {
this.products = products;
this.productsChanged.next(this.products.slice());
}));
}
I suspect it might be a simple fix, but I am struggling to identify what exactly is causing this behavior.
For reference, here is the Stackblitz link: https://stackblitz.com/edit/angular-ivy-w4mbhm
Solution
After some investigation, I have located the issue.
The problem stemmed from my setup listening to (ngModelChange):
<input
name="searchQuery"
type="text"
[(ngModel)]="searchQuery"
(ngModelChange)="onSearch()"
formControlName="searchQuery" />
Within that listener, I inadvertently appended a new listener to 'valueChanges' each time, resulting in the creation of additional listeners upon every keystroke.
A straightforward mistake that led me to spend hours troubleshooting.
Thank you for your assistance!