| 
									
										
										
										
											2017-05-26 21:28:06 +02:00
										 |  |  |  | # Form Validation
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-14 14:22:32 -04:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | Improve overall data quality by validating user input for accuracy and completeness. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-14 12:29:51 -04:00
										 |  |  |  | This page shows how to validate user input in the UI and display useful validation messages | 
					
						
							| 
									
										
										
										
											2017-06-14 14:22:32 -04:00
										 |  |  |  | using first the Template Driven Forms and then the Reactive Forms approach. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | Read more about these choices in the [Forms](guide/forms) | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | and the [Reactive Forms](guide/reactive-forms) guides. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | {@a live-example} | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | **Try the live example to see and download the full cookbook source code.** | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-09 22:01:04 +02:00
										 |  |  |  | <live-example name="form-validation" embedded=true img="guide/form-validation/plunker.png"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | </live-example> | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-14 14:22:32 -04:00
										 |  |  |  | ## Simple Template Driven Forms
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | In the Template Driven approach, you arrange | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | [form elements](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Forms_in_HTML) in the component's template. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | You add Angular form directives (mostly directives beginning `ng...`) to help | 
					
						
							|  |  |  |  | Angular construct a corresponding internal control model that implements form functionality. | 
					
						
							| 
									
										
										
										
											2017-06-14 14:22:32 -04:00
										 |  |  |  | In Template Driven forms, the control model is _implicit_ in the template. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | To validate user input, you add [HTML validation attributes](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation) | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | to the elements. Angular interprets those as well, adding validator functions to the control model. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | Angular exposes information about the state of the controls including | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | whether the user has "touched" the control or made changes and if the control values are valid. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | In this first template validation example, | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | notice the HTML that reads the control state and updates the display appropriately. | 
					
						
							|  |  |  |  | Here's an excerpt from the template HTML for a single input control bound to the hero name: | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 17:21:45 -07:00
										 |  |  |  | <code-example path="form-validation/src/app/template/hero-form-template1.component.html" region="name-with-error-msg" title="template/hero-form-template1.component.html (Hero name)" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | Note the following: | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | * The `<input>` element carries the HTML validation attributes: `required`, `minlength`, and `maxlength`. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | * The `name` attribute of the input is set to `"name"` so Angular can track this input element and associate it | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | with an Angular form control called `name` in its internal control model. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | * The `[(ngModel)]` directive allows two-way data binding between the input box to the `hero.name` property. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | * The template variable (`#name`) has the value `"ngModel"` (always `ngModel`). | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | This gives you a reference to the Angular `NgModel` directive | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | associated with this control that you can use _in the template_ | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | to check for control states such as `valid` and `dirty`. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-10 10:01:54 +01:00
										 |  |  |  | * The `*ngIf` on the `<div>` element reveals a set of nested message `divs` | 
					
						
							| 
									
										
										
										
											2017-06-14 12:29:51 -04:00
										 |  |  |  | but only if there are `name` errors and | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | the control is either `dirty` or `touched`. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | * Each nested `<div>` can present a custom message for one of the possible validation errors. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | There are messages for `required`, `minlength`, and `maxlength`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | The full template repeats this kind of layout for each data entry control on the form. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | {@a why-check} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | #### Why check _dirty_ and _touched_?
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | The app shouldn't show errors for a new hero before the user has had a chance to edit the value. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | The checks for `dirty` and `touched` prevent premature display of errors. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | Learn about `dirty` and `touched` in the [Forms](guide/forms) guide. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | The component class manages the hero model used in the data binding | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | as well as other code to support the view. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 17:21:45 -07:00
										 |  |  |  | <code-example path="form-validation/src/app/template/hero-form-template1.component.ts" region="class" title="template/hero-form-template1.component.ts (class)"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-14 14:22:32 -04:00
										 |  |  |  | Use this Template Driven validation technique when working with static forms with simple, standard validation rules. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-14 14:22:32 -04:00
										 |  |  |  | Here are the complete files for the first version of `HeroFormTemplateCompononent` in the Template Driven approach: | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | <code-tabs> | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 17:21:45 -07:00
										 |  |  |  |   <code-pane title="template/hero-form-template1.component.html" path="form-validation/src/app/template/hero-form-template1.component.html"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 17:21:45 -07:00
										 |  |  |  |   <code-pane title="template/hero-form-template1.component.ts" path="form-validation/src/app/template/hero-form-template1.component.ts"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | </code-tabs> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-14 14:22:32 -04:00
										 |  |  |  | ## Template Driven Forms with validation messages in code
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | While the layout is straightforward, | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | there are obvious shortcomings with the way it's handling validation messages: | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | * It takes a lot of HTML to represent all possible error conditions. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | This gets out of hand when there are many controls and many validation rules. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | * There's a lot of JavaScript logic in the HTML. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | * The messages are static strings, hard-coded into the template. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | It's easier to maintain _dynamic_ messages in the component class. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | In this example, you can move the logic and the messages into the component with a few changes to | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | the template and component. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | Here's the hero name again, excerpted from the revised template | 
					
						
							| 
									
										
										
										
											2017-06-14 14:22:32 -04:00
										 |  |  |  | (template 2), next to the original version: | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | <code-tabs> | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 17:21:45 -07:00
										 |  |  |  |   <code-pane title="hero-form-template2.component.html (name #2)" path="form-validation/src/app/template/hero-form-template2.component.html" region="name-with-error-msg"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 17:21:45 -07:00
										 |  |  |  |   <code-pane title="hero-form-template1.component.html (name #1)" path="form-validation/src/app/template/hero-form-template1.component.html" region="name-with-error-msg"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | </code-tabs> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | The `<input>` element HTML is almost the same. There are noteworthy differences: | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | * The hard-code error message `<divs>` are gone. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | * There's a new attribute, `forbiddenName`, that is actually a custom validation directive. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | It invalidates the control if the user enters "bob" in the name `<input>`([try it](guide/form-validation#live-example)). | 
					
						
							| 
									
										
										
										
											2017-06-14 12:29:51 -04:00
										 |  |  |  | See the [custom validation](guide/form-validation#custom-validation) section later in this page for more information | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | on custom validation directives. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | * The `#name` template variable is gone because the app no longer refers to the Angular control for this element. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-14 12:29:51 -04:00
										 |  |  |  | * Binding to the new `formErrors.name` property is sufficient to display all name validation error messages. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | {@a component-class} | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | ### Component class
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | The original component code for Template 1 stayed the same; however, | 
					
						
							|  |  |  |  | Template 2 requires some changes in the component. This section covers the code | 
					
						
							|  |  |  |  | necessary in Template 2's component class to acquire the Angular | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | form control and compose error messages. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | The first step is to acquire the form control that Angular created from the template by querying for it. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | Look back at the top of the component template at the | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | `#heroForm` template variable in the `<form>` element: | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 17:21:45 -07:00
										 |  |  |  | <code-example path="form-validation/src/app/template/hero-form-template1.component.html" region="form-tag" title="template/hero-form-template1.component.html (form tag)" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | The `heroForm` variable is a reference to the control model that Angular derived from the template. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | Tell Angular to inject that model into the component class's `currentForm` property using a `@ViewChild` query: | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 17:21:45 -07:00
										 |  |  |  | <code-example path="form-validation/src/app/template/hero-form-template2.component.ts" region="view-child" title="template/hero-form-template2.component.ts (heroForm)" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | Some observations: | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | * Angular `@ViewChild` queries for a template variable when you pass it | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | the name of that variable as a string (`'heroForm'` in this case). | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | * The `heroForm` object changes several times during the life of the component, most notably when you add a new hero. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | Periodically inspecting it reveals these changes. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-14 12:29:51 -04:00
										 |  |  |  | * Angular calls the `ngAfterViewChecked()` [lifecycle hook method](guide/lifecycle-hooks#afterview) | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | when anything changes in the view. | 
					
						
							|  |  |  |  | That's the right time to see if there's a new `heroForm` object. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | * When there _is_ a new `heroForm` model, `formChanged()` subscribes to its `valueChanges` _Observable_ property. | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | The `onValueChanged` handler looks for validation errors after every keystroke. | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 17:21:45 -07:00
										 |  |  |  | <code-example path="form-validation/src/app/template/hero-form-template2.component.ts" region="handler" title="template/hero-form-template2.component.ts (handler)" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | The `onValueChanged` handler interprets user data entry. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | The `data` object passed into the handler contains the current element values. | 
					
						
							|  |  |  |  | The handler ignores them. Instead, it iterates over the fields of the component's `formErrors` object. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | The `formErrors` is a dictionary of the hero fields that have validation rules and their current error messages. | 
					
						
							|  |  |  |  | Only two hero properties have validation rules, `name` and `power`. | 
					
						
							|  |  |  |  | The messages are empty strings when the hero data are valid. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | For each field, the `onValueChanged` handler does the following: | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  |   * Clears the prior error message, if any. | 
					
						
							|  |  |  |  |   * Acquires the field's corresponding Angular form control. | 
					
						
							|  |  |  |  |   * If such a control exists _and_ it's been changed ("dirty") | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  |   _and_ it's invalid, the handler composes a consolidated error message for all of the control's errors. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-14 12:29:51 -04:00
										 |  |  |  | Next, the component needs some error messages—a set for each validated property with | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | one message per validation rule: | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 17:21:45 -07:00
										 |  |  |  | <code-example path="form-validation/src/app/template/hero-form-template2.component.ts" region="messages" title="template/hero-form-template2.component.ts (messages)" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | Now every time the user makes a change, the `onValueChanged` handler checks for validation errors and produces messages accordingly. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | {@a improvement} | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | ### The benefits of messages in code
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | Clearly the template got substantially smaller while the component code got substantially larger. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | It's not easy to see the benefit when there are just three fields and only two of them have validation rules. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | Consider what happens as the number of validated | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | fields and rules increases. | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | In general, HTML is harder to read and maintain than code. | 
					
						
							|  |  |  |  | The initial template was already large and threatening to get rapidly worse | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | with the addition of more validation message `<div>` elements. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | After moving the validation messaging to the component, | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | the template grows more slowly and proportionally. | 
					
						
							|  |  |  |  | Each field has approximately the same number of lines no matter its number of validation rules. | 
					
						
							|  |  |  |  | The component also grows proportionally, at the rate of one line per validated field | 
					
						
							|  |  |  |  | and one line per validation message. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | Now that the messages are in code, you have more flexibility and can compose messages more efficiently. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | You can refactor the messages out of the component, perhaps to a service class that retrieves them from the server. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | In short, there are more opportunities to improve message handling now that text and logic have moved from template to code. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | {@a formmodule} | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-14 14:22:32 -04:00
										 |  |  |  | ### _FormModule_ and Template Driven forms
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | Angular has two different forms modules—`FormsModule` and | 
					
						
							|  |  |  |  | `ReactiveFormsModule`—that correspond with the | 
					
						
							|  |  |  |  | two approaches to form development. Both modules come | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | from the same `@angular/forms` library package. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-14 14:22:32 -04:00
										 |  |  |  | You've been reviewing the Template Driven approach which requires the `FormsModule`. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | Here's how you imported it in the `HeroFormTemplateModule`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 17:21:45 -07:00
										 |  |  |  | <code-example path="form-validation/src/app/template/hero-form-template.module.ts" title="template/hero-form-template.module.ts" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | This guide hasn't talked about the `SharedModule` or its `SubmittedComponent` which appears at the bottom of every | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | form template in this cookbook. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 15:36:40 +00:00
										 |  |  |  | They're not germane to the validation story. Look at the [live example](guide/form-validation#live-example) if you're interested. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | {@a reactive} | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-14 14:22:32 -04:00
										 |  |  |  | ## Reactive Forms with validation in code
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-14 14:22:32 -04:00
										 |  |  |  | In the Template Driven approach, you mark up the template with form elements, validation attributes, | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | and `ng...` directives from the Angular `FormsModule`. | 
					
						
							|  |  |  |  | At runtime, Angular interprets the template and derives its _form control model_. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-14 14:22:32 -04:00
										 |  |  |  | **Reactive Forms** takes a different approach. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | You create the form control model in code. You write the template with form elements | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  |  | and `form...` directives from the Angular `ReactiveFormsModule`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | At runtime, Angular binds the template elements to your control model based on your instructions. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | This allows you to do the following: | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | * Add, change, and remove validation functions on the fly. | 
					
						
							|  |  |  |  | * Manipulate the control model dynamically from within the component. | 
					
						
							| 
									
										
										
										
											2017-07-10 10:01:54 +01:00
										 |  |  |  | * [Test](guide/form-validation#testing-considerations) validation and control logic with isolated unit tests. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-14 14:22:32 -04:00
										 |  |  |  | The following sample re-writes the hero form in Reactive Forms style. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | {@a reactive-forms-module} | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | ### Switch to the _ReactiveFormsModule_
 | 
					
						
							| 
									
										
										
										
											2017-06-14 14:22:32 -04:00
										 |  |  |  | The Reactive Forms classes and directives come from the Angular `ReactiveFormsModule`, not the `FormsModule`. | 
					
						
							|  |  |  |  | The application module for the Reactive Forms feature in this sample looks like this: | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 17:21:45 -07:00
										 |  |  |  | <code-example path="form-validation/src/app/reactive/hero-form-reactive.module.ts" title="src/app/reactive/hero-form-reactive.module.ts" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-14 14:22:32 -04:00
										 |  |  |  | The Reactive Forms feature module and component are in the `src/app/reactive` folder. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | Focus on the `HeroFormReactiveComponent` there, starting with its template. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | {@a reactive-component-template} | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | ### Component template
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | Begin by changing the `<form>` tag so that it binds the Angular `formGroup` directive in the template | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | to the `heroForm` property in the component class. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | The `heroForm` is the control model that the component class builds and maintains. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 17:21:45 -07:00
										 |  |  |  | <code-example path="form-validation/src/app/reactive/hero-form-reactive.component.html" region="form-tag" title="form-validation/src/app/reactive/hero-form-reactive.component.html" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-14 14:22:32 -04:00
										 |  |  |  | Next, modify the template HTML elements to match the Reactive Forms style. | 
					
						
							|  |  |  |  | Here is the "name" portion of the template again, revised for Reactive Forms and compared with the Template Driven version: | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | <code-tabs> | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 17:21:45 -07:00
										 |  |  |  |   <code-pane title="hero-form-reactive.component.html (name #3)" path="form-validation/src/app/reactive/hero-form-reactive.component.html" region="name-with-error-msg"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   </code-pane> | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 17:21:45 -07:00
										 |  |  |  |   <code-pane title="hero-form-template1.component.html (name #2)" path="form-validation/src/app/template/hero-form-template2.component.html" region="name-with-error-msg"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | </code-tabs> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | Key changes are: | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | * The validation attributes are gone (except `required`) because | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | validating happens in code. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | * `required` remains, not for validation purposes (that's in the code), | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | but rather for css styling and accessibility. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-14 14:22:32 -04:00
										 |  |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-10 10:01:54 +01:00
										 |  |  |  | Currently, Reactive Forms doesn't add the `required` or `aria-required` | 
					
						
							| 
									
										
										
										
											2017-06-14 14:22:32 -04:00
										 |  |  |  | HTML validation attribute to the DOM element | 
					
						
							|  |  |  |  | when the control has the `required` validator function. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | Until then, apply the `required` attribute _and_ add the `Validator.required` function | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | to the control model, as you'll see below. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-14 14:22:32 -04:00
										 |  |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | * The `formControlName` replaces the `name` attribute; it serves the same | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | purpose of correlating the input with the Angular form control. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | * The two-way `[(ngModel)]` binding is gone. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | The reactive approach does not use data binding to move data into and out of the form controls. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | That's all in code. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | {@a reactive-component-class} | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | ### Component class
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | The component class is now responsible for defining and managing the form control model. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | Angular no longer derives the control model from the template so you can no longer query for it. | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | You can create the Angular form control model explicitly with | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | the help of the `FormBuilder` class. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-14 14:22:32 -04:00
										 |  |  |  | Here's the section of code devoted to that process, paired with the Template Driven code it replaces: | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | <code-tabs> | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 17:21:45 -07:00
										 |  |  |  |   <code-pane title="reactive/hero-form-reactive.component.ts (FormBuilder)" path="form-validation/src/app/reactive/hero-form-reactive.component.ts" region="form-builder"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 17:21:45 -07:00
										 |  |  |  |   <code-pane title="template/hero-form-template2.component.ts (ViewChild)" path="form-validation/src/app/template/hero-form-template2.component.ts" region="view-child"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | </code-tabs> | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | * Inject `FormBuilder` in a constructor. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | * Call a `buildForm` method in the `ngOnInit` [lifecycle hook method](guide/lifecycle-hooks#hooks-overview) | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | because that's when you'll have the hero data. Call it again in the `addHero` method. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | A real app would retrieve the hero asynchronously from a data service, a task best performed in the `ngOnInit` hook. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | * The `buildForm` method uses the `FormBuilder`, `fb`, to declare the form control model. | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | Then it attaches the same `onValueChanged` handler (there's a one line difference) | 
					
						
							|  |  |  |  | to the form's `valueChanges` event and calls it immediately | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | to set error messages for the new control model. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-17 23:17:14 -04:00
										 |  |  |  | ## Built-in validators
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-10 10:01:54 +01:00
										 |  |  |  | Angular forms include a number of built-in validator functions, which are functions | 
					
						
							|  |  |  |  | that help you check common user input in forms. In addition to the built-in | 
					
						
							|  |  |  |  | validators covered here of `minlength`, `maxlength`, | 
					
						
							|  |  |  |  | and `required`, there are others such as `email` and `pattern` | 
					
						
							|  |  |  |  | for Reactive Forms. | 
					
						
							|  |  |  |  | For a full list of built-in validators, | 
					
						
							| 
									
										
										
										
											2017-06-17 23:17:14 -04:00
										 |  |  |  | see the [Validators](api/forms/Validators) API reference. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | #### _FormBuilder_ declaration
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | The `FormBuilder` declaration object specifies the three controls of the sample's hero form. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | Each control spec is a control name with an array value. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | The first array element is the current value of the corresponding hero field. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | The optional second value is a validator function or an array of validator functions. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | Most of the validator functions are stock validators provided by Angular as static methods of the `Validators` class. | 
					
						
							|  |  |  |  | Angular has stock validators that correspond to the standard HTML validation attributes. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 13:37:28 -07:00
										 |  |  |  | The `forbiddenName` validator on the `"name"` control is a custom validator, | 
					
						
							| 
									
										
										
										
											2017-03-11 15:36:40 +00:00
										 |  |  |  | discussed in a separate [section below](guide/form-validation#custom-validation). | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | Learn more about `FormBuilder` in the [Introduction to FormBuilder](guide/reactive-forms#formbuilder) section of Reactive Forms guide. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | #### Committing hero value changes
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | In two-way data binding, the user's changes flow automatically from the controls back to the data model properties. | 
					
						
							| 
									
										
										
										
											2017-07-10 10:01:54 +01:00
										 |  |  |  | A Reactive Forms component should not use data binding to | 
					
						
							| 
									
										
										
										
											2017-06-14 14:22:32 -04:00
										 |  |  |  | automatically update data model properties. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | The developer decides _when and how_ to update the data model from control values. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | This sample updates the model twice: | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 1. When the user submits the form. | 
					
						
							|  |  |  |  | 1. When the user adds a new hero. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | The `onSubmit()` method simply replaces the `hero` object with the combined values of the form: | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 17:21:45 -07:00
										 |  |  |  | <code-example path="form-validation/src/app/reactive/hero-form-reactive.component.ts" region="on-submit" title="form-validation/src/app/reactive/hero-form-reactive.component.ts" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | The `addHero()` method discards pending changes and creates a brand new `hero` model object. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 17:21:45 -07:00
										 |  |  |  | <code-example path="form-validation/src/app/reactive/hero-form-reactive.component.ts" region="add-hero" title="form-validation/src/app/reactive/hero-form-reactive.component.ts" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | </code-example> | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | Then it calls `buildForm()` again which replaces the previous `heroForm` control model with a new one. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | The `<form>` tag's `[formGroup]` binding refreshes the page with the new control model. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-14 14:22:32 -04:00
										 |  |  |  | Here's the complete reactive component file, compared to the two Template Driven component files. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | <code-tabs> | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 17:21:45 -07:00
										 |  |  |  |   <code-pane title="reactive/hero-form-reactive.component.ts (#3)" path="form-validation/src/app/reactive/hero-form-reactive.component.ts"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   </code-pane> | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 17:21:45 -07:00
										 |  |  |  |   <code-pane title="template/hero-form-template2.component.ts (#2)" path="form-validation/src/app/template/hero-form-template2.component.ts"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 17:21:45 -07:00
										 |  |  |  |   <code-pane title="template/hero-form-template1.component.ts (#1)" path="form-validation/src/app/template/hero-form-template1.component.ts"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | </code-tabs> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | Run the [live example](guide/form-validation#live-example) to see how the reactive form behaves, | 
					
						
							| 
									
										
										
										
											2017-06-14 12:29:51 -04:00
										 |  |  |  | and to compare all of the files in this sample. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | ## Custom validation
 | 
					
						
							| 
									
										
										
										
											2017-04-21 13:37:28 -07:00
										 |  |  |  | This cookbook sample has a custom `forbiddenNameValidator()` function that's applied to both the | 
					
						
							| 
									
										
										
										
											2017-06-14 14:22:32 -04:00
										 |  |  |  | Template Driven and the reactive form controls. It's in the `src/app/shared` folder | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | and declared in the `SharedModule`. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 13:37:28 -07:00
										 |  |  |  | Here's the `forbiddenNameValidator()` function: | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 17:21:45 -07:00
										 |  |  |  | <code-example path="form-validation/src/app/shared/forbidden-name.directive.ts" region="custom-validator" title="shared/forbidden-name.directive.ts (forbiddenNameValidator)" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | The function is actually a factory that takes a regular expression to detect a _specific_ forbidden name | 
					
						
							|  |  |  |  | and returns a validator function. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | In this sample, the forbidden name is "bob"; | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | the validator rejects any hero name containing "bob". | 
					
						
							|  |  |  |  | Elsewhere it could reject "alice" or any name that the configuring regular expression matches. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | The `forbiddenNameValidator` factory returns the configured validator function. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | That function takes an Angular control object and returns _either_ | 
					
						
							|  |  |  |  | null if the control value is valid _or_ a validation error object. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | The validation error object typically has a property whose name is the validation key, `'forbiddenName'`, | 
					
						
							|  |  |  |  | and whose value is an arbitrary dictionary of values that you could insert into an error message (`{name}`). | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | ### Custom validation directive
 | 
					
						
							| 
									
										
										
										
											2017-06-14 14:22:32 -04:00
										 |  |  |  | In the Reactive Forms component, the `'name'` control's validator function list | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | has a `forbiddenNameValidator` at the bottom. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 17:21:45 -07:00
										 |  |  |  | <code-example path="form-validation/src/app/reactive/hero-form-reactive.component.ts" region="name-validators" title="reactive/hero-form-reactive.component.ts (name validators)" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-14 14:22:32 -04:00
										 |  |  |  | In the Template Driven example, the `<input>` has the selector (`forbiddenName`) | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | of a custom _attribute directive_, which rejects "bob". | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 17:21:45 -07:00
										 |  |  |  | <code-example path="form-validation/src/app/template/hero-form-template2.component.html" region="name-input" title="template/hero-form-template2.component.html (name input)" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | The corresponding `ForbiddenValidatorDirective` is a wrapper around the `forbiddenNameValidator`. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | Angular `forms` recognizes the directive's role in the validation process because the directive registers itself | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | with the `NG_VALIDATORS` provider, a provider with an extensible collection of validation directives. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 17:21:45 -07:00
										 |  |  |  | <code-example path="form-validation/src/app/shared/forbidden-name.directive.ts" region="directive-providers" title="shared/forbidden-name.directive.ts (providers)" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | </code-example> | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | Here is the rest of the directive to help you get an idea of how it all comes together: | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 17:21:45 -07:00
										 |  |  |  | <code-example path="form-validation/src/app/shared/forbidden-name.directive.ts" region="directive" title="shared/forbidden-name.directive.ts (directive)"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | </code-example> | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | If you are familiar with Angular validations, you may have noticed | 
					
						
							|  |  |  |  | that the custom validation directive is instantiated with `useExisting` | 
					
						
							|  |  |  |  | rather than `useClass`. The registered validator must be _this instance_ of | 
					
						
							|  |  |  |  | the `ForbiddenValidatorDirective`—the instance in the form with | 
					
						
							|  |  |  |  | its `forbiddenName` property bound to “bob". If you were to replace | 
					
						
							|  |  |  |  | `useExisting` with `useClass`, then you’d be registering a new class instance, one that | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | doesn’t have a `forbiddenName`. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | To see this in action, run the example and then type “bob” in the name of Hero Form 2. | 
					
						
							|  |  |  |  | Notice that you get a validation error. Now change from `useExisting` to `useClass` and try again. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | This time, when you type “bob”, there's no "bob" error message. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | For more information on attaching behavior to elements, | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |  | see [Attribute Directives](guide/attribute-directives). | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## Testing Considerations
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-14 14:22:32 -04:00
										 |  |  |  | You can write _isolated unit tests_ of validation and control logic in Reactive Forms. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | _Isolated unit tests_ probe the component class directly, independent of its | 
					
						
							|  |  |  |  | interactions with its template, the DOM, other dependencies, or Angular itself. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | Such tests have minimal setup, are quick to write, and easy to maintain. | 
					
						
							|  |  |  |  | They do not require the `Angular TestBed` or asynchronous testing practices. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-14 14:22:32 -04:00
										 |  |  |  | That's not possible with Template Driven forms. | 
					
						
							|  |  |  |  | The Template Driven approach relies on Angular to produce the control model and | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |  | to derive validation rules from the HTML validation attributes. | 
					
						
							|  |  |  |  | You must use the `Angular TestBed` to create component test instances, | 
					
						
							|  |  |  |  | write asynchronous tests, and interact with the DOM. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  | While not difficult, this takes more time, work and | 
					
						
							|  |  |  |  | skill—factors that tend to diminish test code | 
					
						
							| 
									
										
										
										
											2017-04-21 13:37:28 -07:00
										 |  |  |  | coverage and quality. |