w3resource

Reactive Forms

Introduction

Reactive forms provide a model-driven approach to handling form inputs whose values change over time.

Reactive forms use an explicit and immutable approach to managing the state of a form at a given point in time. Each change to the form state returns a new state, which maintains the integrity of the model between changes. Reactive forms are built around observable streams, where the form inputs and values are provided as streams of input values, which can be accessed synchronously.

They also provide a straightforward path to testing because you are assured that your data is consistent and predictable when requested. Any consumers of the streams have access to manipulate that data safely.

Getting started

As hands-on we will describe how to add a simple form control. In this example, the user enters their name into an input field, captures that input value, and displays the current value of the form control element.

Step 1: Registering the reactive forms module

Reactive forms are registered by importing ReactiveFormsModule from the @angular/forms package and add it to your NgModule's imports array.

TypeScript Code:

import { ReactiveFormsModule } from '@angular/forms';

@NgModule({
  imports: [
    // other imports ...
    ReactiveFormsModule
  ],
})
export class AppModule { }

Live Demo:

It is just a code snippet explaining a particular concept and may not have any output

See the Pen ReactiveForm_registeringform by w3resource (@w3resource) on CodePen.


Step 2: Generating and importing a new form control

We generate a component for control using the following command

ng generate component NameEditor

The FormControl class is the basic building block when using reactive forms. To register a single form control, import the FormControl class into your component and create a new instance of the form control to save as a class property.

Use the constructor of FormControl to set its initial value, which in this case is an empty string. By creating these controls in your component class, you get immediate access to listen for, update, and validate the state of the form input.

Step 3: Registering the control in the template

TypeScript Code:

import { Component } from '@angular/core';
import { FormControl } from '@angular/forms';

@Component({
  selector: 'app-name-editor',
  templateUrl: './name-editor.component.html',
  styleUrls: ['./name-editor.component.css']
})
export class NameEditorComponent {
  name = new FormControl('');
}

Live Demo:

It is just a code snippet explaining a particular concept and may not have any output

See the Pen reactiveForm_registeringFormControl by w3resource (@w3resource) on CodePen.


Once the creation of the control in the component class is done, we then associate it with a form control element in the template.

<label>
  Name:
  <input type="text" [formControl]="name">
</label>

Displaying the component

The form control assigned to name is displayed when the component is added to a template.

TypeScript Code:

<app-name-editor></app-name-editor>

Managing control values

Reactive forms give you access to the form control state and value at a point in time. You can manipulate the current state and value through the component class or the component template.

Displaying a form control value

You can display the value in these ways:

  • Through the valueChanges observable where you can listen for changes in the form's value in the template using AsyncPipe or in the component class using the subscribe() method.
  • With the value property. which gives you a snapshot of the current value.

The following example shows you how to display the current value using interpolation in the template.

name-editor.component.html

<p>
  Value: {{ name.value }}
</p>

The displayed value changes as you update the form control element.

Reactive forms provide access to information about a given control through properties and methods provided with each instance. These properties and methods of the underlying AbstractControl class are used to control form state and determine when to display messages when handling validation.

Generating form controls with FormBuilder

FormBuilder service provides convenient methods for generating controls.

Step 1: Importing the FormBuilder class

Import the FormBuilder class from the @angular/forms package.

profile-editor.component.ts

import { FormBuilder } from '@angular/forms';

Step 2: Injecting the FormBuilder service

The FormBuilder service is an injectable provider that is provided with the reactive forms module. Inject this dependency by adding it to the component constructor.

profile-editor.component.ts

constructor(private fb: FormBuilder) { }

Step 3: Generating form controls

The FormBuilder service has three methods: control(), group(), and array(). These are factory methods for generating instances in your component classes including form controls, form groups, and form arrays.

profile.editor.component.ts(form builder)

TypeScript Code:

import { Component } from '@angular/core';
import { FormBuilder } from '@angular/forms';
 
@Component({
  selector: 'app-profile-editor',
  templateUrl: './profile-editor.component.html',
  styleUrls: ['./profile-editor.component.css']
})
export class ProfileEditorComponent {
  profileForm = this.fb.group({
    firstName: [''],
    lastName: [''],
    address: this.fb.group({
      street: [''],
      city: [''],
      state: [''],
      zip: ['']
    }),
  });
 
  constructor(private fb: FormBuilder) { }
}

Live Demo:

It is just a code snippet explaining a particular concept and may not have any output

See the Pen profile-editor.component.ts by w3resource (@w3resource) on CodePen.


Previous: Pipes
Next: Template driven forms



Follow us on Facebook and Twitter for latest update.