10

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.

6
  • can you try with Validators.compose() which accepts multiple validators against one field. Commented Sep 9, 2017 at 12:19
  • 1
    Yes use compose(): validator: Validators.compose([[PasswordValidation.PasswordMatch, PasswordValidation.PasswordRule])} Commented Sep 9, 2017 at 15:39
  • @Vega does not work Commented Sep 9, 2017 at 17:40
  • You have the same error or it doesn't validate? Commented Sep 9, 2017 at 17:41
  • 2
    @Vega O It is working, thanks. your comment made me to check it again,I was so bored! thank you so much Commented Sep 9, 2017 at 17:46

1 Answer 1

10

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

Sign up to request clarification or add additional context in comments.

2 Comments

I've tested it, but no success because validators.compose accepts validarots which returns observable or promise :/
@Parid0kht I think you are talking about async validators but from your code you are using only static sync validators. For sync validators Observable or Promise is not required. I have updated my answer with the explanation why you are not able to pass the validators as an array to the formbuilder.group() method.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.