Lesson 1.0 Introduction to Form Models

This lesson introduces you to the objectives and structure for this course.

Main Ideas in this Lesson:

  • Introduce Form Models
  • Creating a mental model for understanding reactive forms
  • Introducing FormControls, FormGroups, and FormArrays
  • Introducing important parts of the Forms API

Transcript for this lesson:

Let's talk form models. 
To start, let’s review the mental model we discussed in our previous lesson.
Pictured, we have our control that we create in our component class.
We have a form element or component in our template.
And we have a directive that we use a to bind the control to that element. This mechanism is called the ControlValueAccessor.
Let’s try to move from this high-level understanding into some of the details, starting with how to create a Control object.
All three types of controls extend the AbstractControl abstract class. These three types are the [next] FormControl, [next] the FormGroup, [next] and the FormArray.
To create a FormControl, we simply initialize a FormControl as you can see here. In this case we are passing in an empty string, which signifies that the value of the FormControl is the given empty string.
Initializing a FormGroup is quite similar. Our new FromGroup declaration takes in an object of named AbstractControls, in the scenario below, these are simply FormControls, but as we’ll see in the lessons, these could be FormArrays or other nested FormGroups as well.
Finally here’s the syntax for creating a new FormArray. We simply pass in an array of AbstractControls, and again these are FormControls in the pictured example, but they could be other FormArrays or FormGroups potentially.
So looking at the types of form controls there’s a clear analogy between the different types of FormControls and JavaScript primitives, objects, and arrays.
I actually think there’s also a strong correlation between the different types of FormControls and destructured declarations.
A form control is like a straight-forward declaration - that can declare either a primitive, an array or an object.
A FormGroup is then like the destructured declaration of an object and its properties, where each property of the object is explicitly named as part of the declaration.
FormArray is then like the destructured declaration of an array, where the declaration is an array of the contents of the array, each of which could itself be a primitive, an object, or an array.
Let’s take a look at the AbstractControl API to see just how we can use these controls once they’ve been created.
Possibly the most important part of the PAI is the value property. This is a read-only value that contains the value of the control. We'll use this quite often to synchronously get the value held by a control.
Note that the type for value is any. This is a purposeful decision on the part of the Forms API so that Controls may contain data of any kind of shape.
Closely related to value is the ValueChanges observable stream. This as an observable of any changes to the control’s value. Any time the value changes, we can expect that the observable will emit an event containing the new value.
One other piece we’ll specifically touch on in our lessons is the updateOn strategy. This strategy will dictate when the valueChange events are emitted. By default this is every keystroke, but we can also set it to only emit on blur the corresponding element, which can be very helpful when this is the desired behavior.
Moving along in the API, onscreen we have all the methods that are available to an abstract control. 
Take note of the setValue method. This is what we’ll use to programmatically change the value of a control, since the value property is purposefully read-only by design.
Also note the enable and disable methods - we’ll use these in the upcoming lessons to enable or disable input elements programmatically.
Let’s tie all this together back with our mental model - and peel down from this high level into some actual code.
Here we declare a new FormControl for our component class.
And we see form element that we wish to bind to this control, so we add the directive to the target element, and they are now properly bound.
This means we can call methods within our component class and our DOM will accurately reflect those changes.
Let’s jump into our next lesson so we can see this in action!