@title Reactive Forms @intro Create a reactive form using FormBuilder, groups, and arrays. @description _Reactive forms_ is an Angular technique for creating forms in a _reactive_ style. This guide explains reactive forms as you follow the steps to build a "Hero Detail Editor" form. {@a toc} ## Contents * [Introduction to reactive forms](guide/reactive-forms#intro) * [Setup](guide/reactive-forms#setup) * [Create a data model](guide/reactive-forms#data-model) * [Create a _reactive forms_ component](guide/reactive-forms#create-component) * [Create its template file](guide/reactive-forms#create-template) * [Import the _ReactiveFormsModule_](guide/reactive-forms#import) * [Display the _HeroDetailComponent_](guide/reactive-forms#update) * [Add a FormGroup](guide/reactive-forms#formgroup) * [Taking a look at the form model](guide/reactive-forms#json) * [Introduction to _FormBuilder_](guide/reactive-forms#formbuilder) * [Validators.required](guide/reactive-forms#validators) * [Nested FormGroups](guide/reactive-forms#grouping) * [Inspect _FormControl_ properties](guide/reactive-forms#properties) * [Set form model data using _setValue_ and _patchValue_](guide/reactive-forms#set-data) * [Use _FormArray_ to present an array of _FormGroups_](guide/reactive-forms#form-array) * [Observe control changes](guide/reactive-forms#observe-control) * [Save form data](guide/reactive-forms#save) Try the Reactive Forms live-example. You can also run the Reactive Forms Demo version and choose one of the intermediate steps from the "demo picker" at the top. {@a intro} ## Introduction to Reactive Forms Angular offers two form-building technologies: _reactive_ forms and _template-driven_ forms. The two technologies belong to the `@angular/forms` library and share a common set of form control classes. But they diverge markedly in philosophy, programming style, and technique. They even have their own modules: the `ReactiveFormsModule` and the `FormsModule`. ### _Reactive_ forms Angular _reactive_ forms facilitate a _reactive style_ of programming that favors explicit management of the data flowing between a non-UI _data model_ (typically retrieved from a server) and a UI-oriented _form model_ that retains the states and values of the HTML controls on screen. Reactive forms offer the ease of using reactive patterns, testing, and validation. With _reactive_ forms, you create a tree of Angular form control objects in the component class and bind them to native form control elements in the component template, using techniques described in this guide. You create and manipulate form control objects directly in the component class. As the component class has immediate access to both the data model and the form control structure, you can push data model values into the form controls and pull user-changed values back out. The component can observe changes in form control state and react to those changes. One advantage of working with form control objects directly is that value and validity updates are [always synchronous and under your control](guide/reactive-forms#async-vs-sync "Async vs sync"). You won't encounter the timing issues that sometimes plague a template-driven form and reactive forms can be easier to unit test. In keeping with the reactive paradigm, the component preserves the immutability of the _data model_, treating it as a pure source of original values. Rather than update the data model directly, the component extracts user changes and forwards them to an external component or service, which does something with them (such as saving them) and returns a new _data model_ to the component that reflects the updated model state. Using reactive form directives does not require you to follow all reactive priniciples, but it does facilitate the reactive programming approach should you choose to use it. ### _Template-driven_ forms _Template-driven_ forms, introduced in the [Template guide](guide/forms), take a completely different approach. You place HTML form controls (such as `` and ``.
Disregard the `form-control` _CSS_ class. It belongs to the Bootstrap CSS library, not Angular. It _styles_ the form but in no way impacts the logic of the form.
{@a import} ## Import the _ReactiveFormsModule_ The HeroDetailComponent template uses `formControlName` directive from the `ReactiveFormsModule`. In this sample, you declare the `HeroDetailComponent` in the `AppModule`. Therefore, do the following three things in `app.module.ts`: 1. Use a JavaScript `import` statement to access the `ReactiveFormsModule` and the `HeroDetailComponent`. 1. Add `ReactiveFormsModule` to the `AppModule`'s `imports` list. 1. Add `HeroDetailComponent` to the declarations array. {@a update} ## Display the _HeroDetailComponent_ Revise the `AppComponent` template so it displays the `HeroDetailComponent`. {@a essentials} ### Essential form classes It may be helpful to read a brief description of the core form classes. * [_AbstractControl_](api/forms/AbstractControl "API Reference: AbstractControl") is the abstract base class for the three concrete form control classes: `FormControl`, `FormGroup`, and `FormArray`. It provides their common behaviors and properties, some of which are _observable_. * [_FormControl_](api/forms/FormControl "API Reference: FormControl") tracks the value and validity status of an _individual_ form control. It corresponds to an HTML form control such as an input box or selector. * [_FormGroup_](api/forms/FormGroup "API Reference: FormGroup") tracks the value and validity state of a _group_ of `AbstractControl` instances. The group's properties include its child controls. The top-level form in your component is a `FormGroup`. * [_FormArray_](api/forms/FormArray "API Reference: FormArray") tracks the value and validity state of a numerically indexed _array_ of `AbstractControl` instances. You'll learn more about these classes as you work through this guide. ### Style the app You used bootstrap CSS classes in the template HTML of both the `AppComponent` and the `HeroDetailComponent`. Add the `bootstrap` _CSS stylesheet_ to the head of `index.html`: Now that everything is wired up, the browser should display something like this:
Single FormControl
{@a formgroup} ## Add a FormGroup Usually, if you have multiple *FormControls*, you'll want to register them within a parent `FormGroup`. This is simple to do. To add a `FormGroup`, add it to the imports section of `hero-detail.component.ts`: In the class, wrap the `FormControl` in a `FormGroup` called `heroForm` as follows: Now that you've made changes in the class, they need to be reflected in the template. Update `hero-detail.component.html` by replacing it with the following. Notice that now the single input is in a `form` element. The `novalidate` attribute in the `
` element prevents the browser from attempting native HTML validations. `formGroup` is a reactive form directive that takes an existing `FormGroup` instance and associates it with an HTML element. In this case, it associates the `FormGroup` you saved as `heroForm` with the form element. Because the class now has a `FormGroup`, you must update the template syntax for associating the input with the corresponding `FormControl` in the component class. Without a parent `FormGroup`, `[formControl]="name"` worked earlier because that directive can stand alone, that is, it works without being in a `FormGroup`. With a parent `FormGroup`, the `name` input needs the syntax `formControlName=name` in order to be associated with the correct `FormControl` in the class. This syntax tells Angular to look for the parent `FormGroup`, in this case `heroForm`, and then _inside_ that group to look for a `FormControl` called `name`.
Disregard the `form-group` _CSS_ class. It belongs to the Bootstrap CSS library, not Angular. Like the `form-control` class, it _styles_ the form but in no way impacts its logic.
The form looks great. But does it work? When the user enters a name, where does the value go? {@a json} ## Taking a look at the form model The value goes into the **_form model_** that backs the group's `FormControls`. To see the form model, add the following line after the closing `form` tag in the `hero-detail.component.html`: The `heroForm.value` returns the _form model_. Piping it through the `JsonPipe` renders the model as JSON in the browser:
JSON output
The initial `name` property value is the empty string. Type into the _name_ input box and watch the keystokes appear in the JSON. Great! You have the basics of a form. In real life apps, forms get big fast. `FormBuilder` makes form development and maintenance easier. {@a formbuilder} ## Introduction to _FormBuilder_ The `FormBuilder` class helps reduce repetition and clutter by handling details of control creation for you. To use `FormBuilder`, you need to import it into `hero-detail.component.ts`: Use it now to refactor the `HeroDetailComponent` into something that's a little easier to read and write, by following this plan: * Explicitly declare the type of the `heroForm` property to be `FormGroup`; you'll initialize it later. * Inject a `FormBuilder` into the constructor. * Add a new method that uses the `FormBuilder` to define the `heroForm`; call it `createForm`. * Call `createForm` in the constructor. The revised `HeroDetailComponent` looks like this: `FormBuilder.group` is a factory method that creates a `FormGroup`.   `FormBuilder.group` takes an object whose keys and values are `FormControl` names and their definitions. In this example, the `name` control is defined by its initial data value, an empty string. Defining a group of controls in a single object makes for a compact, readable style. It beats writing an equivalent series of `new FormControl(...)` statements. {@a validators} ### Validators.required Though this guide doesn't go deeply into validations, here is one example that demonstrates the simplicity of using `Validators.required` in reactive forms. First, import the `Validators` symbol. To make the `name` `FormControl` required, replace the `name` property in the `FormGroup` with an array. The first item is the initial value for `name`; the second is the required validator, `Validators.required`.
Reactive validators are simple, composable functions. Configuring validation is harder in template-driven forms where you must wrap validators in a directive.
Update the diagnostic message at the bottom of the template to display the form's validity status. The browser displays the following:
Single FormControl
`Validators.required` is working. The status is `INVALID` because the input box has no value. Type into the input box to see the status change from `INVALID` to `VALID`. In a real app, you'd replace the diagnosic message with a user-friendly experience. Using `Validators.required` is optional for the rest of the guide. It remains in each of the following examples with the same configuration. For more on validating Angular forms, see the [Form Validation](guide/form-validation) guide. ### More FormControls A hero has more than a name. A hero has an address, a super power and sometimes a sidekick too. The address has a state property. The user will select a state with a `