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.
A validator function returns true if the form field is valid according to the validator rules, or false otherwise. A validator can be plugged in directly into a reactive form simply by adding it to the validators list. Each form field has its own list of separate validators.
FormBuilder allows us to explicitly declare forms in our components. This allows us to also explicitly list each form control's validators.
When the user changes the value in the watched field, the control is marked as "dirty" When the user blurs the form control element, the control is marked as "touched"
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
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