Reputation: 166
I have an input search element that I detect keyup and I want to use debounce to limit request made to the API but I can't get it working. I'm just trying to test debounceTime and distinctUntilChanged.
I have already tried (Keyup) but can't get it working.
<input (keyup)="onKeyUp($event)" id="testInput" autocomplete="off" type="text" name="searchFilterText" class="m-list-search__form-input" value="" placeholder="Search...">
Here is the code from the typescript file.
searchInput = document.getElementById('testInput');
observable: any;
/// <summary>
/// Process the search term provided on key up for the input field.
/// </summary>
/// <param name="searchTerm">The search term.</param>
onKeyUp(event: KeyboardEvent) {
//console.log(event);
let element = event.target as HTMLInputElement;
let value = element.value;
this.observable = fromEvent(this.searchInput, event.type)
.debounceTime(500) // millisecs until value gets emitted.
.distinctUntilChanged()
.subscribe(function (event) {
console.log(event.target.value);
});
}
The expected result is a delayed search result value in the console log using debounceTime and distinctUntilChanged.
Upvotes: 2
Views: 7664
Reputation: 60548
You could try this:
Template
<input
id="testInput" autocomplete="off"
type="text" #searchText
name="searchFilterText" class="m-list-search__form-input"
value=""
placeholder="Search...">
Notice the template reference variable: #searchText
. This allows access to the input element without needing getElementById
(which is not normally recommended to use in an Angular app).
Component
import { Component, AfterViewInit, ViewChild } from '@angular/core';
import { fromEvent } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
@Component({
templateUrl: './search.component.html'
})
export class SearchComponent implements AfterViewInit {
@ViewChild('searchText') searchTextRef;
ngAfterViewInit() {
if (this.searchTextRef) {
fromEvent(this.searchTextRef.nativeElement, 'keyup')
.pipe(
debounceTime(500),
distinctUntilChanged()
).subscribe(
value => console.log(this.searchTextRef.nativeElement.value)
)
}
}
}
This code uses @ViewChild
to get the reference to the element marked with the #searchText
template reference variable.
It then uses code similar to what you had for the debounceTime
.
I have a stackblitz here: https://stackblitz.com/edit/angular-debounce-deborahk
And you can find more info here: Observable.fromEvent - RXJS
Note: This is even easier if you use reactive forms as you can directly access the valueChanges
observable for any input element on a form.
Reactive Forms
Template
<input
id="testInput"
[formControl]="search"
autocomplete="off"
type="text"
class="m-list-search__form-input"
value=""
placeholder="Search...">
Notice the formControl
directive.
Component
// For reactive forms
search = new FormControl();
ngOnInit() {
this.search.valueChanges
.pipe(
debounceTime(500),
distinctUntilChanged()
).subscribe(
value => console.log("Reactive Forms implementation: " + value)
)
}
Upvotes: 9