When I press a key on a form input for some reason the async validator doesn't detect the distinctUntilChanged and it still sends API requests. for example if I press 35, delete 5 and after that add 5 again it still sends the request. this is the code: (I've tried pretty much everything but still doesn't work)
validateSomeNumber(control: FormControl): Observable<any> | Promise <any> {
this.isSubmitBtnDisabled = true;
return control.valueChanges.pipe(
debounceTime(1000),
distinctUntilChanged(),
switchMap((value) => {
return this.apiService.someApiRequest({ 'to_number': control.value }).pipe(
map(res => {
console.log(res);
if (res.success) {
// console.log(res);
this.isSubmitBtnDisabled = false;
return null;
} else {
// console.log(res);
this.isSubmitBtnDisabled = true;
return{ 'invalidCharacters': true };
}
}),
);
}),
first()
);
}
By default
validateSomeNumber
is called after every value change.If you return this on every value change
you're creating a new Observable of value changes on every value change. e.g if you type four characters you end up with four independent Observables each emitting one character and not with one Observable emitting four times. So
debounceTime
anddistinctUntilChanged
will only effecting the Observable you create on a particular value change but not the value change process as a whole. If they only effect an Observable that emits once they obviously don't work as you intend them to do.You should return the http request directly
Limiting the request frequency
Option 1: updateOn
To prevent the http request from being executed on every value change Angular recommends changing the
updateOn
property tosubmit
orblur
.With template-driven forms:
With reactive forms:
{updateOn: 'blur'}
will only execute the validators when your input looses focus.Option 2: Emulate debounceTime and distinctUntilChanged
Angular automatically unsubscribes from the previous Observable returned by the AsyncValidator if the form value changes. This allows you to emulate
debounceTime
withtimer
. To emulatedistinctUntilChanged
you can keep track of the last request term and do the equality check yourself.