I have a form where the administrator can create a new user. I would like to validate the username field is unique. I have create a uniqueUserNameValidator however this function always returns null. I belive this happens beacouse the service is a async method. I need the result of the async before continuing I have tried to add a await bad this also creates weird problem. How can I fix this issues thank you for your help.
Here is where I want to use the validator
this.userService.getEmployeeById(this.employeeId).subscribe(result => {
this.employee = result;
this.employeeDetailForm = new FormGroup({
userName: new FormControl(this.employee.userName, [Validators.required, this.uniqueUserNameValidator.bind(this)])
});
Here is my validator
private uniqueUserNameValidator(control: FormControl): { [s: string]: boolean } {
this.employee.userName = control.value;
var userExists: boolean;
this.userService.checkIfEmployeeUserNameExists(this.employee).subscribe(data => {
userExists = data;
})
if (userExists) {
return { userExists: true };
}
return null;
}
Here is the service in question
checkIfEmployeeUserNameExists(employee: Employee) {
return this.http.put<boolean>(this.baseUrl 'employees/isUserNameUnique', employee)
}
CodePudding user response:
As other users already pointed out in the comments, you should use an async validator to get the behavior that you want. When creating a new control, you can pass in validatorOrOpts
as the second parameter. This allows you a finer control over the validators that you can set.
this.employeeDetailForm = new FormGroup({
userName: new FormControl(this.employee.userName, {
validators: [Validators.required],
asyncValidators: [this.partnerCodeAvailabilityValidator.bind(this)]
})
});
The partnerCodeAvailabilityValidator
should look like this:
private partnerCodeAvailabilityValidator(
control: AbstractControl
): Observable<ValidationErrors | null> {
this.employee.userName = control.value;
return this.userService
.checkIfEmployeeUserNameExists(this.employee)
.pipe(map((data) => ({ userExists: data })));
}
Alternatively, you could build a directive and implement the AsyncValidator
interface in case you want to use it with template driven forms.