2

I'm creating a form with Angular2 and I created two custom validators for email address field.

The first validator checks for email validity, the second (async) validator checks if email address already exists on database. In addition I would like to add a third validator for another verification.

Here is my code:

'email': ['', [validateEmail(), thirdValidator()], asyncValidator]

The behaviour that I want is the following: Only when the first validator validates the control, the second validator should start. And only when the second validator terminates then the third validator can start its validation.

How to reach this?

1 Answer 1

3

Validators.compose method should do the job, example:

   let formControls = {
        'oldPassword': new FormControl({ value: ''}),
        'newPassword': new FormControl({ value: ''}, Validators.compose([customValidator1, customValidator2]), customAsyncValidator)
    };

Composed validators work simultaneously, meaning we can have multiple errors on the control at the same time (each validator attaches its own error if validation failed). If we need to have only one error on the control at a time, we can 'chain' validators by checking the status of the previous validation before performing next one. Something like this:

    let customValidator2 = (ctrl: FormControl): any => {
        if(ctrl.hasError('customValidationError1')) {
            // there is the error attached by customValidator1, 
            // skip executing customValidator2 (nullify its error)
            return null;
        }

        let isInvalid = true; // some condition...

        return isInvalid ? { customValidationError2: true } : null;
    }

This way we can accomplish 'ordering' the validators by their priority for example.

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

14 Comments

I didn't know that method... anyway it seems not be the answer to my question: Compose multiple validators into a single function that returns the union of the individual error maps. Isn't it like to use [validateEmail(), thirdValidator()] ?
I've updated the answer. Validators do not work in sequence they've been provided. We can have multiple errors on one field ofc. However we can manually rein them as in the example above.
Ok, that's fine for me. Thank you. Anyway it seems that validators in sequence work in AND. Is this right? In addition, can you tell me what is the difference between putting validators in sequence and using compose method?
Either way they work simultaneously I think, there shouldn't be difference, however I will check it to make sure.
Yes, it also means that the ctrl isn't validated (since the first validation shows the error, we want to skip the second validation by marking it valid). I guess the same logic could be applied to async validators.
|

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.