Last update on Sunday, February 12th 2017

Angular 2 Reactive Forms in One Go

Another sweet and short tuts today!
Following the article on the Template-Driven Forms here, we switch to Reactive Forms also called Model-Driven Forms.
We will skip the User Model this time and just focus on the form itself.

As usual we start by adding the corresponding module to our app.module file:

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

@NgModule({
  imports: [
    .
    .
    .
    ReactiveFormsModule
    .
    .
    .
  ]
  .
  .
  .
})

Switching to our HomeComponent controller:

import { Component } from "@angular/core";
import { FormGroup, FormBuilder } from "@angular/forms";

@Component({
  selector: "my-home",
  templateUrl: "./home.component.html"
})
export class HomeComponent {
  userForm: FormGroup;

  constructor(formBuilder: FormBuilder) {
    this.userForm = formBuilder.group({
      name: "",
      email: "",
      address: formBuilder.group({
        country: "",
        city: ""
      })
    });
  }

  onFormSubmitted(form) {
    console.log("form value:", form.value);
    // Rest of the logic here
  }
}

All we need here is FormBuilder (I also imported FromGroup but it's only for clear typing).
Once again we will stock our form values in the userForm variable.
formBuilder will create the root level group and pass it to userForm.
Finally we build the address sub-group by asking formBuilder to give us another group.
Keep in mind that each properties of the groups (name, email, country and city) are FormControls.

And that's it!

We are ready to use our form in this HTML template:

<form [formGroup]="userForm" (ngSubmit)="onFormSubmitted(userForm)">
  <label>
    <span>Name</span>
    <input type="text" formControlName="name" placeholder="Name" required>
  </label>
  <div>
    <label>
      <span>Email</span>
      <input type="email" formControlName="email" placeholder="Email" required>
    </label>
  </div>
  <div formGroupName="address">
    <label>
      <span>Country</span>
      <input type="text" formControlName="country" placeholder="Country" required>
    </label>
    <div>
      <label>
        <span>City</span>
        <input type="text" formControlName="city" placeholder="City" required>
      </label>
    </div>
  </div>
  <input type="submit" [disabled]="userForm.invalid">
</form>

So compared to the Template-Driven method what changed here?
Only 3 new words: formGroup, formControlName and formGroupName.

  • formGroup links our previously created userForm
  • formControlName links our formControls (name, email ...)
  • formGroupName links our address formGroup

On submit we will have our form available in our onFormSubmitted function. I'd like to dive deeper however we will need more knowledge about Observables. So let's keep it light for now.

Next week, Observables!
Stay tuned.

Stay up to date


Join over 4000 other developers who already receive my tutorials and their source code out of the oven + other free stuff!