I am using Angular 11 and creating a simple reactive form with a formcontrolname 'name'. when user types in this field, i need to validate for uniqueness. I tried following but it validates for every time i type something, but want to use debouncetime and use similar logic. Not sure how to do this with reactive form
Can anyone help me how to achieve this?
I end up with the following AsyncVaildator. Can anyone please help me if this can be simplified? Because i am passing the service to the method. is there a way to use dependency injection here?
export class TemplateNameValidator {
createValidator(auditTemplateService: AuditTemplateService): AsyncValidatorFn {
console.log("Static factory call");
return (control: AbstractControl): Observable<ValidationErrors> => {
if(isEmptyInputValue(control.value)) {
return of(null);
} else {
return control.valueChanges.pipe(
debounceTime(500),
distinctUntilChanged(),
take(1),
switchMap((name: string) =>
auditTemplateService.isNameUnique(name)
.pipe(
map(isUnique => !isUnique ? { 'duplicate': true } : null)
)
)
);
}
};
}
}
function isEmptyInputValue(value: any): boolean {
return value === null || value.length === 0;
}
private registerFormGroup(): void {
this.nameField = new FormControl(
{ value: this.auditTemplate.title, disabled: true },
[Validators.compose([
Validators.required,
(control) => this.isNameUnique(control as AbstractControl)
])]
);
this.templateForm = this.formBuilder.group({
templateName: this.nameField,
tags: [this.auditTemplate.tags]
});
}
validation to check uniqueness:
isNameUnique(formField: AbstractControl): { [key: string] : any} {
const nameEntered = formField.value;
let isDuplicate = false;
if(nameEntered && this.availableNames) {
const index = this.availableNames.findIndex(templateName =>
templateName.name === nameEntered);
if(index !== -1) {
isDuplicate = true;
}
}
return isDuplicate ? { 'duplicate': true } : null;
}
Thanks