Angular 8/9 Reactive Forms Validation with Angular Material 8 Last updated on August 4, 2020 by Digamber

#01 – Setup Angular Project To work with Reactive Forms in Angular 8/9 we must have a basic project setup. Follow the process to setup the project. ng new angular8-reactive-forms Ge into the project’s folder. cd angular8-reactive-forms

#02 – Implement Angular Material UI Library in Angular 8/9 Project. To create reactive forms demo, We’ll be using Angular material ui library. Angular material offers lots of beautiful components we’ll be using Angular material library’s forms component to create and validate Reactive forms. Run the cmd to setup Angular material library. ng add @angular/material Select the Angular material theme from the options: ? Choose a prebuilt theme name, or "custom" for a custom theme: Indigo/Pink ❯ Indigo/Pink [ Preview: https://material.angular.io?theme = indigo-pink ] Deep Purple/Amber [ Preview: https://material.angular.io?theme = deeppurple-amber ] Pink/Blue Grey [ Preview: https://material.angular.io?theme = pink-bluegrey ] Purple/Green [ Preview: https://material.angular.io?theme = purple-green ] Select yes and hit enter. Create material.module.ts file in app folder and paste the below code. import { NgModule } from '@angular/core' ; import { CommonModule } from '@angular/common' ; import { MatBadgeModule } from '@angular/material/badge' ; import { MatButtonModule } from '@angular/material/button' ; import { MatChipsModule } from '@angular/material/chips' ; import { MatNativeDateModule } from '@angular/material/core' ; import { MatDatepickerModule } from '@angular/material/datepicker' ; import { MatFormFieldModule } from '@angular/material/form-field' ; import { MatGridListModule } from '@angular/material/grid-list' ; import { MatIconModule } from '@angular/material/icon' ; import { MatInputModule } from '@angular/material/input' ; import { MatListModule } from '@angular/material/list' ; import { MatPaginatorModule } from '@angular/material/paginator' ; import { MatRadioModule } from '@angular/material/radio' ; import { MatSelectModule } from '@angular/material/select' ; import { MatSidenavModule } from '@angular/material/sidenav' ; import { MatTableModule } from '@angular/material/table' ; import { MatToolbarModule } from '@angular/material/toolbar' ; import { MatTooltipModule } from '@angular/material/tooltip' ; @ NgModule ( { imports : [ CommonModule , MatButtonModule , MatToolbarModule , MatIconModule , MatSidenavModule , MatBadgeModule , MatListModule , MatGridListModule , MatFormFieldModule , MatInputModule , MatSelectModule , MatRadioModule , MatDatepickerModule , MatNativeDateModule , MatChipsModule , MatTooltipModule , MatTableModule , MatPaginatorModule ] , exports : [ MatButtonModule , MatToolbarModule , MatIconModule , MatSidenavModule , MatBadgeModule , MatListModule , MatGridListModule , MatInputModule , MatFormFieldModule , MatSelectModule , MatRadioModule , MatDatepickerModule , MatChipsModule , MatTooltipModule , MatTableModule , MatPaginatorModule ] , providers : [ MatDatepickerModule , ] } ) export class AngularMaterialModule { } Then go to app.module.ts file and paste the following code to enable material.module.ts in Angular app. import { BrowserAnimationsModule } from '@angular/platform-browser/animations' ; import { AngularMaterialModule } from './material.module' ; import { NgModule , CUSTOM_ELEMENTS_SCHEMA } from '@angular/core' ; @ NgModule ( { declarations : [ ... ] , imports : [ BrowserAnimationsModule , AngularMaterialModule , ] , providers : [ ... ] , bootstrap : [ ... ] , schemas : [ CUSTOM_ELEMENTS_SCHEMA ] } ) export class AppModule { } Now we’ll add Angular material 8 theme and Angular material icons in our project. Go to src > index.html file and add the following code in the head section. < link href = " https://fonts.googleapis.com/css?family=Roboto:300,400,500 " rel = " stylesheet " > < link href = " https://fonts.googleapis.com/icon?family=Material+Icons " rel = " stylesheet " > Go to src > styles.css file and add the following code. @import "~@angular/material/prebuilt-themes/indigo-pink.css" ; html,body { height : 100% ; } body { margin : 0 ; font-family : Roboto , "Helvetica Neue" , sans-serif ; } form { width : 420px ; margin : 35px auto 100px ; display : block ; float : none ; } .mat-form-field { width : 100% ; } .misc-bottom-padding { margin : 8px 0 20px ; } .misc-bottom-padding mat-label { margin-right : 15px ; } .mat-radio-label { margin : 0 15px 0 0 ; } .title-center { margin : 0 auto ; } .button-wrapper { margin-top : 10px ; }

#03 – Set Up ReactiveFormsModule in Angular 9 To use Reactive forms in Angular app, we need to import ReactiveFormsModule in app.module.ts file. import { ReactiveFormsModule } from '@angular/forms' ; @ NgModule ( { imports : [ ReactiveFormsModule ] , } ) export class AppModule { }

#04 – Understand Reactive Forms API To manage the data in Angular 9, we need to understand some core APIs of Reactive forms. FormGroup: FormGroup API holds the values, properties, and validation state of a group in Reactive forms.

FormGroup API holds the values, properties, and validation state of a group in Reactive forms. FormBuilder: It offers convenient methods to control the instances.

It offers convenient methods to control the instances. AbstractControl: This class controls the behavior and properties of, FormGroup, FormControl, and FormArray.

This class controls the behavior and properties of, FormGroup, FormControl, and FormArray. FormControl: It is responsible for managing the value and validation status of the specific form control.

It is responsible for managing the value and validation status of the specific form control. FormArray: This API manages the values, properties, and validation state of an array.

This API manages the values, properties, and validation state of an array. ngSubmit: This event is called when the form is submitted. < form [formGroup] = " myForm " (ngSubmit) = " submitForm() " novalidate > < mat-form-field class = " example-full-width " > < input matInput placeholder = " Name " formControlName = " name " > </ mat-form-field > </ form >

#05 – Create Form using Reactive Form and Angular Material 8 We are going to create a form using Angular material 8 UI components. We’ll create a form in Angular 8/9 using FormGroup & FormBuilder Reactive form API. To style Reactive forms we will use Angular material form controls components. Go to app.component.html file and add the following code. < mat-sidenav-container > < mat-sidenav-content > < form [formGroup] = " myForm " (ngSubmit) = " submitForm() " novalidate > < mat-form-field class = " example-full-width " > < input matInput placeholder = " Name " formControlName = " name " > </ mat-form-field > < mat-form-field class = " example-full-width " > < input matInput placeholder = " Email " formControlName = " email " > </ mat-form-field > < div class = " misc-bottom-padding " > < mat-label > Gender: </ mat-label > < mat-radio-group aria-label = " Select an option " formControlName = " gender " > < mat-radio-button value = " Male " > Male </ mat-radio-button > < mat-radio-button value = " Female " > Female </ mat-radio-button > </ mat-radio-group > </ div > < mat-form-field > < input matInput readonly [matDatepicker] = " picker " placeholder = " Date of birth " formControlName = " dob " (dateChange) = " date($event) " > < mat-datepicker-toggle matSuffix [for] = " picker " > </ mat-datepicker-toggle > < mat-datepicker #picker > </ mat-datepicker > </ mat-form-field > < mat-form-field > < mat-label > Grade </ mat-label > < mat-select [(value)] = " selected " formControlName = " grade " > < mat-option [value] = " gradeArray " *ngFor = " let gradeArray of GradeArray " > {{gradeArray}} </ mat-option > </ mat-select > </ mat-form-field > < mat-form-field class = " multiple-items " > < mat-chip-list #chipList > < mat-chip *ngFor = " let subjectsArray of SubjectsArray " [selectable] = " selectable " [removable] = " removable " (removed) = " remove(subjectsArray) " > {{subjectsArray.name}} < mat-icon matChipRemove *ngIf = " removable " > cancel </ mat-icon > </ mat-chip > < input placeholder = " Add subjects " [matChipInputFor] = " chipList " [matChipInputSeparatorKeyCodes] = " separatorKeysCodes " [matChipInputAddOnBlur] = " addOnBlur " (matChipInputTokenEnd) = " add($event) " > </ mat-chip-list > </ mat-form-field > < div class = " button-wrapper " > < button mat-flat-button color = " primary " > Submit </ button > </ div > </ form > </ mat-sidenav-content > </ mat-sidenav-container > Go to app.component.ts file and add the following code. import { Component , ViewChild } from '@angular/core' ; import { COMMA , ENTER } from '@angular/cdk/keycodes' ; import { MatChipInputEvent } from '@angular/material/chips' ; import { FormGroup , FormBuilder } from "@angular/forms" ; export interface Subject { name : string ; } @ Component ( { selector : 'app-root' , templateUrl : './app.component.html' , styleUrls : [ './app.component.css' ] } ) export class AppComponent { visible = true ; selectable = true ; removable = true ; addOnBlur = true ; myForm : FormGroup ; @ ViewChild ( 'chipList' , { static : true } ) chipList ; GradeArray : any = [ '8th Grade' , '9th Grade' , '10th Grade' , '11th Grade' , '12th Grade' ] ; SubjectsArray : Subject [ ] = [ ] ; readonly separatorKeysCodes : number [ ] = [ ENTER , COMMA ] ; constructor ( public fb : FormBuilder ) { } ngOnInit ( ) : void { this . reactiveForm ( ) } reactiveForm ( ) { this . myForm = this . fb . group ( { name : [ '' ] , email : [ '' ] , gender : [ 'Male' ] , dob : [ '' ] , grade : [ '' ] , subjects : [ this . SubjectsArray ] } ) } date ( e ) { var convertDate = new Date ( e . target . value ) . toISOString ( ) . substring ( 0 , 10 ) ; this . myForm . get ( 'dob' ) . setValue ( convertDate , { onlyself : true } ) } add ( event : MatChipInputEvent ) : void { const input = event . input ; const value = event . value ; if ( ( value || '' ) . trim ( ) && this . SubjectsArray . length < 5 ) { this . SubjectsArray . push ( { name : value . trim ( ) } ) } if ( input ) { input . value = '' ; } } remove ( subject : Subject ) : void { const index = this . SubjectsArray . indexOf ( subject ) ; if ( index >= 0 ) { this . SubjectsArray . splice ( index , 1 ) ; } } submitForm ( ) { console . log ( this . myForm . value ) } }

#06 – Setup Angular 8/9 Project for Reactive Forms Demo In next step, we will learn how to validate Reactive forms using Angular material 8. I’ll create a separate function which will handle the errors emitted by reactive forms. Go to your app.component.ts file and add the following function to handle errors. import { FormGroup , FormBuilder , Validators } from "@angular/forms" ; reactiveForm ( ) { this . myForm = this . fb . group ( { name : [ '' , [ Validators . required ] ] , email : [ '' , [ Validators . required ] ] , gender : [ 'Male' ] , dob : [ '' , [ Validators . required ] ] , grade : [ '' ] , subjects : [ this . SubjectsArray ] } ) } Go to your app.component.html file and add the angular material form control errors something like this. < form [formGroup] = " myForm " (ngSubmit) = " submitForm() " novalidate > < mat-form-field > < input matInput placeholder = " Name " formControlName = " name " > < mat-error *ngIf = " errorHandling('name', 'required') " > You must provide a < strong > name </ strong > </ mat-error > </ mat-form-field >

#07 – Radio Buttons with Reactive Forms. In this part of the tutorial, I’ll show you how to manage the data of Radio buttons in reactive forms. We’ll create radio buttons with the help of Angular material and also tell you how to set the selected value of radio buttons. Go to app.component.html file and add the following code. < mat-radio-group aria-label = " Select an option " formControlName = " gender " > < mat-radio-button value = " Male " > Male </ mat-radio-button > < mat-radio-button value = " Female " > Female </ mat-radio-button > </ mat-radio-group > Go to app.component.ts file and add the following code. reactiveForm ( ) { this . myForm = this . fb . group ( { gender : [ 'Male' ] } ) }

#8 – Select Dropdown with Reactive Forms? We’ll look at how to work with select dropdown in Angular 8/9 in this part of the tutorial. We’ll create select dropdown using angular material forms component. To dynamically manage the select dropdown value, We’ll take help of reactive forms. Go to app.component.html file and add the following code. < mat-select [(value)] = " selected " formControlName = " grade " > < mat-option [value] = " gradeArray " *ngFor = " let gradeArray of GradeArray " > {{gradeArray}} </ mat-option > </ mat-select > Go to app.component.ts file and add the following code. export class AppComponent { GradeArray : any = [ '8th Grade' , '9th Grade' , '10th Grade' , '11th Grade' , '12th Grade' ] ; constructor ( public fb : FormBuilder ) { } ngOnInit ( ) : void { this . reactiveForm ( ) } reactiveForm ( ) { this . myForm = this . fb . group ( { grade : [ '' ] } ) } }

#09 – Working with Angular Material Date-picker using Reactive Forms Here we’ll learn to work with dates in Angular 8/9. We’ll cover the following topics: Set Angular material datepicker in Angular app.

Get Angular material datepicker value using (dateChange)="date($event)" in event.

in event. Convert date object to string value Go app.component.html file and include the given below code. < mat-form-field > < input matInput readonly [matDatepicker] = " picker " placeholder = " Date of birth " formControlName = " dob " (dateChange) = " date($event) " > < mat-datepicker-toggle matSuffix [for] = " picker " > </ mat-datepicker-toggle > < mat-datepicker #picker > </ mat-datepicker > </ mat-form-field > Go app.component.ts file and include the given below code. export class AppComponent { constructor ( public fb : FormBuilder ) { } ngOnInit ( ) : void { this . reactiveForm ( ) } reactiveForm ( ) { this . myForm = this . fb . group ( { dob : [ '' ] } ) } date ( e ) { var convertDate = new Date ( e . target . value ) . toISOString ( ) . substring ( 0 , 10 ) ; this . myForm . get ( 'dob' ) . setValue ( convertDate , { onlyself : true } ) } }