Reputation: 23615
I'm implementing debounceTime
in an autocomplete scenario.
I want to use the debounceTime
to limit the number of calls to the server. Google gives me 3 potential solutions, for which I pasted the code below.
All of them however, seem to have some drawbacks in my opinion, so I am looking for the most "Angular" way of implementing it.
fromEvent(document.getElementById('myelement'), 'mouseover').pipe(
debounceTime(1000),
map(data => data.srcElement)
).subscribe(val => console.log(val));
This strikes me as "non-Anular'ish" as the component has a reference to element ID's in the HTML. This creates a dependency from the class to the HTML, in which I already have on the other way around. And it looks like plain JS in stead of "Angular'ish".
this.bookId.valueChanges.pipe(
debounceTime(1000),
switchMap(id => {
console.log(id);
return this.bookService.getBook(id);
})
).subscribe(res => this.book = res);
This one looked the most "Anular'ish", with a subscription on the data-property in the class (bookId
), but it needs reactive forms as I understand, which we do not use (not against it, so this is a possibility for us).
this.subject
.pipe(debounceTime(500))
.subscribe(() => {
this.formGroup.controls.name.setValidators([ Validators.minLength(5) ]);
this.formGroup.controls.name.updateValueAndValidity();
});
onKeyUp(): void {
this.subject.next();
}
<input type="text" formControlName="name" (keyup)="onKeyUp()">
This also doesn't look very "Angular'ish" because it looks like plain JavaScript that I catch and process DOM events. I thought that, in my opinion, this is not an Angular way of working?
Upvotes: 1
Views: 78
Reputation: 2672
Options 2 and 3 look Angular'ish. However, you can make option 1 also angularish.
Angular has a concept of ViewChild to get DOM elements into component class. You can use Angular's ngAfterViewInit life-cycle hook to get the DOM element. One way would be this:
@ViewChild ('myName', { static: false }) myName;
ngAfterViewInit() {
fromEvent(this.myName.nativeElement, 'mouseover').pipe(debounceTime(1000),
tap(data => console.log(data)),
map(data => data.srcElement)
).subscribe(val => console.log(val));
}
You can see this stackblitz for more details: https://stackblitz.com/edit/angular-fotgbf
Upvotes: 1