I have two custom validator
in a reactive form
, I call function below to create form in component constructor:
private createForm(): void {
this.passwordUpdateForm = this.formBuilder.group({
newpassword : [null, Validators.required],
passwordconfirm: [null, Validators.required]
},
{
validator: [PasswordValidation.PasswordMatch, PasswordValidation.PasswordRule] // validation method
});
}
PasswordValidation is a class with two functions like below
export class PasswordValidation {
public static PasswordMatch(control: AbstractControl) {
let password = control.get('newpassword'); // to get value in input tag
if(password){
let confirmPassword = control.get('passwordconfirm').value; // to get value in input tag
if (password.value !== confirmPassword) {
control.get('passwordconfirm').setErrors({ ['passwordmatch'] : true});
}else {
return null;
}
}
}
public static PasswordRule(control: AbstractControl) {
let password = control.get('newpassword').value; // to get value in input tag
let pattern = new RegExp('^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,64}');
if (!pattern.test(password)) {
control.get('newpassword').setErrors({ ['passwordrule'] : true});
}else if (password.toLowerCase() === 'something') {
control.get('newpassword').setErrors({ ['passwordrule'] : true});
}else {
return null;
}
}
}
each custom validator works fine separately like this
validator: PasswordValidation.PasswordMatch
or this
validator: PasswordValidation.PasswordRule
but using both of them in array like
validator: [PasswordValidation.PasswordMatch, PasswordValidation.PasswordRule]
get error this.validator is not a function
and does not work, I do not have any idea, please help.
its better to use Validators.compose([])
which accepts the array of validators to be used on the specific user control in the form group.
for example if you want to add the validators against the passwordconfirm
and newpassword
control you can do it like below
private createForm(): void {
this.passwordUpdateForm = this.formBuilder.group({
newpassword : [null, Validators.compose([Validators.required,PasswordValidation.PasswordRule])],
passwordconfirm: [null, Validators.compose([Validators.required, PasswordValidation.PasswordMatch])]
});
under the hood this is what the code looks like
group(controlsConfig: {[key: string]: any}, extra: {[key: string]: any} = null): FormGroup {
const controls = this._reduceControls(controlsConfig);
const validator: ValidatorFn = isPresent(extra) ? extra['validator'] : null;
const asyncValidator: AsyncValidatorFn = isPresent(extra) ? extra['asyncValidator'] : null;
return new FormGroup(controls, validator, asyncValidator);
}
you can see the paramater validator
is actually a type of interface ValidatorFn
which looks like below
interface ValidatorFn {
(c: AbstractControl): ValidationErrors|null
}
so you can see it can accept any method that has the above signature.
Source : https://angular.io/api/forms/ValidatorFn
Check this link for more : https://toddmotto.com/reactive-formgroup-validation-angular-2