1

I want to add some delay in making network request when I type in search bar. So I can prevent unnecessary network request.

header.component.ts

searchProduct(event: KeyboardEvent) {
    if (event) {
      const { value } = event.target as HTMLInputElement;
      this.productService.searchProducts(value).subscribe((res) => {
        console.log(res);
        if (res.length > 5) {
          res.length = 5;
        }
        this.searchResult = res;
      });
    }

product.service.ts

searchProducts(query: string) {
    return this.http.get<Prodcut[]>(`http://localhost:3000/products?q=${query}`);
  }
Amar
  • 11
  • 2
  • Does this answer your question? [How to cancel a HTTPRequest in Angular 2?](https://stackoverflow.com/questions/36490926/how-to-cancel-a-httprequest-in-angular-2) – Sivakumar Tadisetti Oct 09 '22 at 06:07

2 Answers2

2

The switchMap will cancel any HTTP request that hasn't been completed if a new value is emitted through the subject. You can play with the debouneTime to see what feels right for you.

this.searchBar.on('change', () => {

    of(this.serachBar.searchText).pipe(
        debounceTime(400),
        distinctUntilChanged(),
        switchMap((text) => {
            return this.productService.searchProducts(text).map(resp => {
                console.log(res);
                if (res.length > 5) {
                    res.length = 5;
                }
                return res;
            });
        });
    ).subscribe(response => console.log(response));

});
cfprabhu
  • 5,267
  • 2
  • 21
  • 30
  • I am trying with this code but no matter how much is debounce time I gave, still I'm getting immediate console logs. can you please telll what is wrong I'm doing here? searchProduct(event: KeyboardEvent) { if (event) { const { value } = event.target as HTMLInputElement; if (value !== '') { of(value) .pipe(debounceTime(40000)) .subscribe((res) => { console.log(`res is ${res}`); }); } } } – Amar Oct 09 '22 at 16:50
  • searchQuery: string; // bind this to input with ngModel searchQueryChanged: Subject < string > = new Subject(); onFieldChange(query: string){ this.searchQueryChanged.next(query); } – cfprabhu Oct 09 '22 at 17:49
  • //add this inside ngOnInit this.searchQueryChanged.pipe( debounceTime(400), distinctUntilChanged(), switchMap((text) => { return this.productService.searchProducts(text).map(resp => { console.log(res); if (res.length > 5) { res.length = 5; } return res; }); }) ).subscribe(response => console.log(response)); – cfprabhu Oct 09 '22 at 17:49
0

I would suggest not to cancel the previous request, but to make a delay, if you want to prevent unnecessary network request. Something like this:

this.changeValue$
  .pipe(debounceTime(300))
  .subscribe((event) => {
    this.searchProduct(event);
  });

But in this case, you need to modify the input.

If you still want to cancel, then try:

subsription: Subscription | undefined;

searchProduct(event: KeyboardEvent) {
  if (event) {
    this.subsription?.unsubscribe();
    const { value } = event.target as HTMLInputElement;
    this.subsription = this.productService.searchProducts(value).subscribe((res) => {
    // ...
}
Eugene
  • 1,242
  • 1
  • 10
  • 15