I have a form with a "name" control.
<div class="field">
<label>Name</label>
<input ngControl="name">
<p *ngIf="name.pending">
Fetching data from the server...
</p>
<div *ngIf="!name.valid && !name.pending"
class="ui error message">Name is not valid</div>
</div>
The control is built with FormBuilder like this :
this.name = fb.control('', null, this.characterNameValidator.bind(this));
and I created a validator :
characterNameValidator(control: Control) {
let q = new Promise((resolve, reject) => {
setTimeout(() => {
if (this._characterService.isCharacterNameAlreadyExists(control.value)) {
resolve({nameCharacterAlreadyExistsError: true});
} else {
resolve(null);
}
}, 1000)
});
return q;
}
On each keystroke, my validator is called. I'm looking for a way to call the validator only after a debounce time.
I try with valueChanges(), but I understand only if I call a specific service but not in the case of validation.
Edit
Is it a good idea to manage validation manually to achieve my problem ? I don't put a validator in my control but I set errors manually on valueChanges.
this.name = fb.control('');
this.name.valueChanges.debounceTime(400).subscribe(() => {
this.characterNameValidator(this.name).then((validationResult => {
this.name.setErrors(validationResult)
}))
});
See https://github.com/angular/angular/issues/1068 for a related open issue.
If you pass a reference to the control to the validator you could use something like
this.formGp.controls['numberFld'].updateValueAndValidity();
from https://stackoverflow.com/a/33377290/217408
The official way of getting what you want is in upcoming features to form validation.
https://youtu.be/kM5QBOWrUVI?t=9m48s
However, you can manually debounce validation by subscribing to value changes, and setting your own error.
testForm.controls['name'].valueChanges
.do(
res => {
if (res) {
this.testForm.controls['name'].setErrors({loading: true});
}
}
)
.debounceTime(500)
.subscribe(
res => {
if (this.nameSub) {
this.nameSub.unsubscribe();
this.nameSub = null;
}
this.nameSub = this.http.get(apiURL + 'exist/?name=' + res).subscribe(
exists => {
this.testForm.controls['name'].setErrors({nameExists: true});
this.nameSub.unsubscribe();
this.nameSub = null;
},
error => {
if (res) {
this.testForm.controls['name'].setErrors(null);
}
this.nameSub.unsubscribe();
this.nameSub = null;
}
);
},
error => {}
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With