You are on page 1of 33

Header

Microsoft Virtual Academy

Mastering Angular, Part 4


Reactive Forms
Eric W. Greene

Produced by
• What are Reactive Forms?
• Getting Started with Angular
• Demo: Setting Up the Angular Starter Application
• Using a Form Control
• Demo: Creating a Profile Form
• Using a Form Group
• Demo: Using a Form Group with the Profile Form
• Group Related Form Controls with a Nested Form Group
• Demo: Group the Address Controls
• Dynamically Adding and Removing Form Controls
• Demo: Collecting Multiple Addresses
• Building Forms with the Form Builder Service
• Demo: Using Form Builder to create the Profile Form
• Extracting Data from the Form Controls
• Demo: Displaying the collected Profile data
• Angular supports two form systems: Template Forms and Reactive Forms
• Template Forms are covered in the Angular Template Forms course
• Reactive Forms follow the reactive style of programming
• From Wikipedia, "Reactive programming is a programming paradigm
oriented around data flows and propagation of change"1
• With Reactive Forms, the component directly manages the data flows
between the form controls and data models
• Reactive forms are code driven versus template driven
• Imperative vs. Declarative
• Reactive forms break from the most traditional declarative approach
Angular has used in the past, its more similar to React
• Reactive forms eliminate the anti-pattern of updating the data model via
two-way data binding
• Typically, Reactive form control creation is synchronous, and can be unit
tested with synchronous programming techniques
• According to Angular, Template Forms and Reactive Forms are both
good approaches of creating a form in Angular
• Both approaches provide validation and capture form input data from
the user
• With Reactive Forms, the form control tree is created synchronously with
code
• With Template Forms, the form control tree is created asynchronously as
part of the compilation process as directives are processed
• With Reactive Forms, the form control tree is available immediately even
before the child form elements have been created, with Template Forms
the form control tree is available after the child form elements have
• When constructing the form control tree with Reactive Forms, the form
control tree is available during the first change detection cycle, even
before the form elements themselves have been created
• When constructing the form control tree with Template Forms, the form
control tree is not available until the second change detection cycle
because the directives which create the form control tree use the first
cycle to create the various form control tree objects
• Because the form control tree is not available until the second change
detection cycle; therefore, template forms are setup asynchronously
• When unit testing, Template Forms must be tested using asynchronous
testing techniques because of how the form controls are created by
directives as part of the compilation process
• Also, for more advanced forms where access to the form controls early
in the view creation process is required, Template Forms may not be
ready in time
• Honestly, Template Forms represent the older approach to building
Angular applications with two-way data binding
• For simple forms Template Forms is good, for any form beyond the
simplest form, Reactive Forms are best
• NgModel is not included with Reactive Forms
• Behind the scenes, NgModel creates form controls, and pushes/pulls
data to/from the mutable data model when the user interacts with the
form control
• With NgModel, the component has no control over the flow of data
• Because, Reactive Forms focus on managing the explicit flow of data
between form controls and the data model, NgModel is not needed to
manage this process for the component
• When building Reactive Forms, the FormGroup, FormControl &
FormArray classes are the fundamental building blocks of a form
• To simplify the creation of forms, Angular provides a FormBuilder
service
• A Form Group is a collection of Form Controls
• A Form Control is the programmatic connection between the form
control in the template and the TypeScript code for the component
• A Form Array supports a dynamic number of form controls
• The Form Builder service uses an object literal to configure an entire
form
• Angular applications require some initial project configuration to get up
and running
• There are many ways to get started
• Angular CLI
• Numerous Starter Projects
• From Scratch
• This course will use a starter project configured with WebPack 2
• The WebPack development server will serve the web pages, and
WebPack will bundle the application files
• The initial starter project can be downloaded from GitHub
• Git is not required, simply fire up a web browser, and visit the following
link
• https://github.com/training4developers/mastering-angular-starter
• In the demonstration we will download, configure and fire up the project
Demo
Setting Up the Angular Starter Application
• To use Reactive Forms, the ReactiveFormsModule needs to be
imported from the @angular/forms package and registered with the
imports option of the AppModule
• Once registered, the FormControl class needs to imported from the
@angular/forms package into the component file
• A property on the component of type FormControl needs to be defined
and assigned a new instance of the FormControl class
• The default usage constructor of the FormControl class accepts two
arguments: the value of the control, and data validators
• To connect the FormControl instance to an actual control on the form,
the formControl attribute directive is used

public FormControl FormControl


Demo
Creating a Profile Form
• For a form with a single control, a single Form Control object is sufficient
• For a form with many controls, its better to group them together under
a Form Group
• Grouping controls under a form group simplifies the creation and
configuration of form control objects
• Also, form groups provide form validation information aggregated from
the form controls within it
• To create a Form Group, a new instance of a Form Group is created as a
property on the component
• When instantiating the Form Group, an object of Form Controls is
passed into the Form Group
• The Form Group instance is attached to the form element in the
template via the formGroup attribute directive
• Each control in the form is attached to their respective form controls via
the formControlName attribute
public new
new

form formGroup novalidate


div
label for label
input type id formControlName
div
form
Demo
Using a Form Group with the Profile Form
• Within a larger form it can be helpful group related controls in sub-
groups, known as nested form groups
• The FormGroup class can be used for nested form groups as well
public new
new
new
new
new
new
new
new
Demo
Group the Address Controls
Dynamically Adding and Removing Form
Controls
• Dynamic form creation is important in many applications
• The FormGroup and FormArray classes support the ability to add form
controls dynamically
• Creating dynamic forms involves updating the form control tree and the
DOM
• Directives such as ngFor can read the form control tree to create new
input elements when new controls are added
Dynamically Adding and Removing Form
Controls
<fieldset formArrayName="addressGroups">
<legend>Address</legend>
<div
*ngFor="let addressGroup of profileForm.controls['addressGroups'].controls"
[formGroup]="addressGroup">
Street: <input type="text" formControlName="streetControl"><br>
City: <input type="text" formControlName="cityControl"><br>
State: <input type="text" formControlName="stateControl"><br>
Zip Code: <input type="text" formControlName="zipCodeControl"><br>
</div>
</fieldset> const fa = this.profileForm.controls["addressGroups"] as FormArray;

fa.push(new FormGroup({
When the new form streetControl: new FormControl(""),
group is added, the cityControl: new FormControl(""),
ngFor adds a new stateControl: new FormControl(""),
zipCodeControl: new FormControl(""),
div }));
Demo
Collecting Multiple Addresses
Building Forms with the Form Builder Service

• The beauty of ngModel is that almost no code is required to create a


form beyond the HTML template itself
• With Reactive Forms, both the template and form objects need to be
created, essentially doubling the work load
• While benefits of Reactive Forms outweigh the extra work, it would still
be helpful to have a way to reduce the code somewhat to create
Reactive Forms, especially large ones
• Angular Forms provides a service named FormBuilder which allows
Reactive Forms to be more easily created through helper functions
Building Forms with the Form Builder Service

• To use the FormBuilder service, simply inject it into the component, the
construct the form in the constructor of the component (or a separate
function) called by the constructor
• One of the advantages of Reactive Forms is early access to the Form
Control object tree
• Therefore, build the form early even in the constructor to allow for early
access
Building Forms with the Form Builder Service

Traditional Approach

Form Builder Approach


Demo
Using Form Builder to create the Profile Form
• Unlike ngModel and Template Forms, Reactive Forms do not update the
model directly
• Rather, the Form Control object tree is updated, and the data is explicitly
extracted from the tree and then updates the model
• To extract the collected data from the FormGroup, FormControl and
FormArray object, the value property is used
• For FormGroups and FormArrays, which are containers for other
Reactive Form objects, their value properties return all of the form
control data they contain
public profileForm: FormGroup; console.dir(this.profileForm.value);
Demo
Displaying the Collected Profile Data
• Reactive Forms is one of the two approaches to configuring Angular
forms
• Reactive Forms explicitly manages the data flows between form controls
and the underlying data model
• The Reactive Forms classes and services, FormGroup, FormControl,
FormArray, and FormBuilder, are available from @angular/forms
• The FormBuilder service enables Reactive Forms to be more easily
created
• Data collected by Reactive Forms does not automatically update the
data model, code must be written to transfer that data to the data
model

You might also like