2

I'm building an Angular 5 form. I have a requirement for contact information on my form (email or phone). Either an email address OR a phone number is required, but not both. How would I create a custom validator for this scenario? From the docs it seems that validators are responsible for just one control, whereas my validator would need to be aware of multiple controls to check all their values.

ngOnInit() {
   this.form = this.formBuilder.group({
       'name': [null, [Validators.required]],
       'email': [null, []], // A user can provide email OR phone, but
       'phone': [null, []], // both are not required. How would you do this?
   });
}
2

1 Answer 1

10

One possible solution is declaring a function that takes as an argument the form itself, for example:

    export function emailAndPhone() {
      return (form: FormGroup): {[key: string]: any} => {
        return (form.value.phone && form.value.email) ||
               (!form.value.phone && !form.value.email) 
                  ? { emailAndPhoneError : true } 
                  : null;
      };
    }

Set the validator function to your form definition using the validator extras:

ngOnInit() {
   this.form = this.formBuilder.group({
       'name': [null, [Validators.required]],
       'email': [null, []], // A user can provide email OR phone, but
       'phone': [null, []], // both are not required. How would you do this?
   }, { validator: emailAndPhone() });
}

If you need to recognize when the validation has detected an invalid input just make sure that emailAndPhoneError that was defined earlier is present on the form error list. Like this

*ngIf="myForm.hasError('emailAndPhoneError')" //true means invalid
Sign up to request clarification or add additional context in comments.

3 Comments

And where does emailAndPhoneError come from here?
{ emailAndPhoneError : true } is the return value from emailAndPhone() function. It is only returned when your condition is invalid, otherwise it returns null.
@DanielC. Yes, this will be a good starting point to build from. Thanks.

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.