In this tutorial, you’ll learn how to create Angular material Reactive Forms. This is the second part of the Angular Material Reactive Form Tutorial Series. In the first part, you learned how to install Angular material and use the components in the Angular project.

Source code from this tutorial is available on GitHub.

Video Tutorial : How to Create Angular Reactive Forms

Getting Started

Let’s start from where we stopped in the first part. Once you have installed Angular material, install bootstrap framework to your Angular project. You’ll be using Bootstrap along side Angular Material components.

Once you have Bootstrap installed in your project, here is how the styles and scripts from your angular.json file looks:

"styles": [
    "src/styles.css",
    "node_modules/bootstrap/dist/css/bootstrap.min.css"
],
"scripts": [
    "node_modules/jquery/dist/jquery.min.js",
    "node_modules/popper.js/dist/umd/popper.min.js",
    "node_modules/bootstrap/dist/js/bootstrap.min.js"
]

Angular material theme class has been imported in the style.css.

/* You can add global styles to this file, and also import other style files */
@import '@angular/material/prebuilt-themes/indigo-pink.css';
html, body { height: 100%; }
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }

Now we are good to create a form using Angular material.

Creating Angular Material Form

You’ll be using a couple of Angular Material component while creating the form. Let’s start by importing the required component in the app.module.ts file.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatRadioModule } from '@angular/material/radio';
import { MatCardModule } from '@angular/material/card';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatSelectModule } from '@angular/material/select';
import { MatInputModule } from '@angular/material/input';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatNativeDateModule } from '@angular/material/core';
import { MatButtonModule } from '@angular/material/button';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    MatFormFieldModule,
    MatInputModule,
    MatSelectModule,
    MatRadioModule,
    MatCardModule,
    MatButtonModule,
    MatDatepickerModule,
    MatNativeDateModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Now let’s create the HTML for the profile form using material components. Add the following to app.component.html file.

<form class="form-container">
    <mat-card>
      <mat-card-header>
        <mat-card-title>Profile Information</mat-card-title>
      </mat-card-header>
      <mat-card-content>
        <div class="row">
          <div class="col-md-6">
            <mat-form-field class="full-width">
              <input matinput="" placeholder="First name">
            </mat-form-field>
          </div>
          <div class="col-md-6">
            <mat-form-field class="full-width">
              <input matinput="" placeholder="Last name">
            </mat-form-field>
          </div>
        </div>
        <div class="row">
          <div class="col-sm-6">
            <mat-form-field class="full-width">
              <textarea matinput="" placeholder="Address"></textarea>
            </mat-form-field>
          </div>
          <div class="col-md-6 top-padding">
                <mat-form-field class="full-width" appearance="fill">
                    <mat-label>Select DOB</mat-label>
                    &lt;input matInput [matDatepicker]="picker"&gt;
                    &lt;mat-datepicker-toggle matSuffix [for]="picker"&gt;&lt;/mat-datepicker-toggle&gt;
                    &lt;mat-datepicker #picker&gt;&lt;/mat-datepicker&gt;
                </mat-form-field>                  
            </div>
        </div>
        <div class="row">
            <div class="col-md-12">
                <mat-radio-group class="margin-left">
                    <mat-radio-button value="male"> Male </mat-radio-button>
                    <mat-radio-button value="female"> Female </mat-radio-button>
                </mat-radio-group>
            </div>
        </div>
      </mat-card-content>
      <mat-card-actions>
        <button mat-raised-button="" color="primary">Save</button>
      </mat-card-actions>
    </mat-card>
  </form>

Here is the CSS style for the app.component.css.

.full-width{
    width: 100%;
}

.top-padding{
    padding-top: 3px;
}

.margin-left mat-radio-button:not(:first-child){
    margin-left:10px;
}

.form-container{
    margin: 100px;
}

Save the above changes and restart the Angular app.

npm start

Point your browser to http://localhost:4200 and you’ll be able to see the profile form.

How to Create Angular Material Form

Now since you have the Angular material form ready, let’s move forward and create Angular reactive form.

Create Angular Reactive Form

Before working with Reactive Forms, you need to import FormsModule and ReactiveFormsModule in app.module.ts file:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatRadioModule } from '@angular/material/radio';
import { MatCardModule } from '@angular/material/card';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatSelectModule } from '@angular/material/select';
import { MatInputModule } from '@angular/material/input';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatNativeDateModule } from '@angular/material/core';
import { MatButtonModule } from '@angular/material/button';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    FormsModule,
    ReactiveFormsModule,
    MatFormFieldModule,
    MatInputModule,
    MatSelectModule,
    MatRadioModule,
    MatCardModule,
    MatButtonModule,
    MatDatepickerModule,
    MatNativeDateModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

To make a form Reactive you’ll be making use of FormBuilder. Import it in app.component.ts file and initialize an instance in constructor.

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  constructor(private formBuilder: FormBuilder) {}
}

Using the formBuilder instance, create a form group with form fields.

profileForm = this.fb.group({
  firstName: [''],
  lastName: [''],
  address: [''],
  dob: [''],
  gender: ['']
});

Now let’s map the profileForm form group to the HTML form template. Add the formGroup and formControlName attribute to the form and form elements respectively in app.component.html.

<form [formGroup]="profileForm" class="form-container">
    <mat-card>
      <mat-card-header>
        <mat-card-title>Profile Information</mat-card-title>
      </mat-card-header>
      <mat-card-content>
        <div class="row">
          <div class="col-md-6">
            <mat-form-field class="full-width">
              <input formcontrolname="firstName" matinput="" placeholder="First name">
            </mat-form-field>
          </div>
          <div class="col-md-6">
            <mat-form-field class="full-width">
              <input formcontrolname="lastName" matinput="" placeholder="Last name">
            </mat-form-field>
          </div>
        </div>
        <div class="row">
          <div class="col-sm-6">
            <mat-form-field class="full-width">
              <textarea formcontrolname="address" matinput="" placeholder="Address"></textarea>
            </mat-form-field>
          </div>
          <div class="col-md-6 top-padding">
                <mat-form-field class="full-width" appearance="fill">
                    <mat-label>Select DOB</mat-label>
                    <input formControlName="dob" matInput [matDatepicker]="picker">
                    <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
                    <mat-datepicker #picker></mat-datepicker>
                </mat-form-field>                  
            </div>
        </div>
        <div class="row">
            <div class="col-md-12">
                <mat-radio-group formcontrolname="gender" class="margin-left">
                    <mat-radio-button value="male"> Male </mat-radio-button>
                    <mat-radio-button value="female"> Female </mat-radio-button>
                </mat-radio-group>
            </div>
        </div>
      </mat-card-content>
      <mat-card-actions>
        <button (click)="onSubmit()" mat-raised-button color="primary">Save</button>
      </mat-card-actions>
    </mat-card>
  </form>

On clicking the button, let’s log the form values to the browser console. Add the onSubmit method to app.component.ts file.

onSubmit() {
  console.log('form data is ', this.profileForm.value);
}

Here is how the complete app.component.ts file looks:

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
 
  constructor(private fb: FormBuilder) {}

  profileForm = this.fb.group({
    firstName: [''],
    lastName: [''],
    address: [''],
    dob: [''],
    gender: ['']
  });

  onSubmit() {
   console.log('form data is ', this.profileForm.value);
  }
}

Save the above changes and start the angular app. Point your browser to http://localhost:4200, enter form details and click the save button. You will have the profile form details logged in the browser console.

Button Click Output in Browser Console

Wrapping It Up

In this second part of the Angular Material Reactive Form Tutorial series, you learnt how to create Angular Reactive Form.

You used the FormBuilder module to create form group and mapped it to the HTML template. You saw how easy it is to access all the form data using Reactive Forms. In this next part, you’ll learn how to add validations to the profile information reactive form that you just created.