Now that you’ve learned about creating a custom validator for one form control, let’s work on custom validation across multiple controls, aka cross-validation. This means you use one control to determine whether another control is valid.

Let’s say that we’re offering the user a free fitness class if they refer a friend. If they enter an email that matches their own, we’ll show them that that’s not allowed, and they’ll get an error message. First things first, we need to give the email and friend email form controls a common parent, a nested FormGroup called emails. We will end up applying our new custom cross-field validator, emailsMatch, to this form group. Inside this validator, we'll get both email & friendemail from the control parameter, e.g. const email = control.get('email').value;. Then we'll return an error with a key of invalidReferral if email === friendemail, otherwise return null.

Remember to make changes in the template that reflect our form model changes. That is, email and friendemail are now in a FormGroup. Outside of the emails FormGroup, the error message should check for emails.invalid && emails.errors?.invalidReferral along with checking friendemail's dirty and touched properties. Note that we also used the safe navigation operator (?) when checking for errors off of emails. This is to protect from throwing a null reference error, and we'll still update to show the error when errors updates to have something in it.