`FormControl` instance, so you can use this in the template to check for control states such as `valid` and `dirty`. For a full list of control properties, see the [AbstractControl](api/forms/AbstractControl)
In a reactive form, the source of truth is the component class. Instead of adding validators through attributes in the template, you add validator functions directly to the form control model in the component class. Angular then calls these functions whenever the value of the control changes.
* **Sync validators**: functions that take a control instance and immediately return either a set of validation errors or `null`. You can pass these in as the second argument when you instantiate a `FormControl`.
The same built-in validators that are available as attributes in template-driven forms, such as `required` and `minlength`, are all available to use as functions from the `Validators` class. For a full list of built-in validators, see the [Validators](api/forms/Validators) API reference.
* The name control sets up two built-in validators—`Validators.required` and `Validators.minLength(4)`—and one custom validator, `forbiddenNameValidator`. For more details see the [Custom validators](guide/form-validation#custom-validators) section in this guide.
* As these validators are all sync validators, you pass them in as the second argument.
* Support multiple validators by passing the functions in as an array.
* This example adds a few getter methods. In a reactive form, you can always access any form control through the `get` method on its parent group, but sometimes it's useful to define getters as shorthands
<code-examplepath="form-validation/src/app/reactive/hero-form-reactive.component.html"region="name-with-error-msg"title="reactive/hero-form-reactive.component.html (name with error msg)"linenums="false">
Once the `ForbiddenValidatorDirective` is ready, you can simply add its selector, `appForbiddenName`, to any input element to activate it. For example:
Like in AngularJS, Angular automatically mirrors many control properties onto the form control element as CSS classes. You can use these classes to style form control elements according to the state of the form. The following classes are currently supported:
This section shows how to perform cross field validation. It assumes some basic knowledge of creating custom validators.
<divclass="l-sub-section">
If you haven't created custom validators before, start by reviewing the [CustomValidators](guide/form-validation#custom-validators).
</div>
In the following section we will make sure that our heroes do not reveal their true identities by filling out the Hero Form. We will do that by validating that the hero names and alter egos do not match. The form has the following structure:
```javascript
const heroForm = new FormGroup({
'name': new FormControl(),
'alterEgo': new FormControl(),
'power': new FormControl()
};
```
Notice that the `name` and `alterEgo` are sibling controls. To evaluate both controls in a single custom validator, we should perform the validation in the ancestor control. That way we can query the form tree for the child controls which will allow us to compare their values.
Identity validator implements the `ValidatorFn` interface. It takes an Angular control object as an argument and returns either null if the form is valid, or ValidationErrors otherwise.
First we retrieve the child controls by calling the `FormGroup`'s [get](api/forms/AbstractControl#get) method. Then we simply compare the values of the `name` and `alterEgo` controls.
If the values do not match the hero's identity remains disguised, and we can safely return null. Otherwise, the hero's identity is revealed and we must mark the form as invalid by returning an error object.
### Adding to reactive forms
As with all reactive forms, the validator can be registered during the form creation. We make sure to register it at the `FormGroup` level, to give it access to the child controls.
- the `FormGroup` has the cross validation error returned by the `identityRevealed` validator,
- the user is yet to [interact](guide/form-validation#why-check-dirty-and-touched) with the form.
Finally, we want to style the `input` elements to give visual feedback about form control's validity. Unfortunately, the `identityRevealed` error is on the form group control (`heroForm`) and not on the child form controls (`name`, `alterEgo`). That means that the `<input formControlName="name" />` and `<input formControlName="alterEgo" />` will not have the `ng-invalid` class after the cross validation fails.
We can get around this problem by binding our own css class to the same expression that was used to show and hide the validation error message.
Below you can inspect the cross validation example for the reactive forms. The example skips over the parts that are not related to cross validation to keep this section focused on a single task. You can see the complete code example at the end of this chapter.
First we must create a directive that will wrap the validator function. We provide it as the validator using the `NG_VALIDATORS` token. If you are not sure why, or you do not fully understand the syntax revisit the previous [section](guide/form-validation#adding-to-template-driven-forms).
Next, we have to add the directive to the html template. Since the validator must be registered at the `FormGroup` level, we put the directive on the `form` tag.
- the `FormGroup` has the cross validation error returned by the `identityRevealed` validator,
- the user is yet to [interact](guide/form-validation#why-check-dirty-and-touched) with the form.
Finally, we want to style the `input` elements to give visual feedback about form control's validity. Unfortunately, the `identityRevealed` error is on the form group control (`heroForm`) and not on the child form controls (`name`, `alterEgo`). That means that the `<input [(ngModel)]="hero.name" />` and `<input [(ngModel)]="hero.alterEgo" />` will not have the `ng-invalid` class after the cross validation fails.
We can get around this problem by binding our own css class to the same expression that was used to show and hide the validation error message.
Below you can inspect the cross validation example for the template-driven forms. The example skips over parts that are not related to cross validation to keep this section focused on a single task. You can see the complete code example at the end of this chapter.