Angular Model-Driven
Angular Model-Driven (Reactive) Forms
Forms come handy when handling user-input and enabling user to log in, update information, and other data-entry tasks. These are basically used to capture user input events. In Angular, there are two approaches to handling user inputs.
- Template-Driven Forms
- Reactive Forms
Template Driven Forms
Template Driven Forms are used to bind the data to the component class using ngModel. We do not need to take the pain of writing code and most of the task is done by Angular itself. There is very less of effort required from the developer to pass information from the component class to the template.
Reactive forms
However, Reactive forms are synchronous and are usually considered when working with database. We write the code for validation inside the component class and also map the objects to the form controls on the view.
In this article, our focus is to work with Reactive Forms which follow the model-driven approach to work with user input and handle it dynamically.
GETTING STARTED WITH REACTIVE FORMS
We will create a Form, using FormGroup, FormControl, FormBuilder class etc. The very first step is to import ReactiveFormsModule in the app.module.ts as listed below :
- import { BrowserModule } from '@angular/platform-browser';
- import { NgModule } from '@angular/core';
- import {ReactiveFormsModule} from '@angular/forms';
- import { AppComponent } from './app.component';
- @NgModule({
- declarations: [
- AppComponent
- ],
- imports: [
- BrowserModule, ReactiveFormsModule
- ],
- providers: [],
- bootstrap: [AppComponent]
- })
- export class AppModule { }
Now there are some important classes that need to be imported inside the component like FormControl, FormArray like listed below :
- import { Component } from '@angular/core';
- import {FormArray, FormControl, FormGroup} from '@angular/forms';
- @Component({
- selector: 'app-root',
- template: ``
- })
- export class AppComponent {
- title = 'Reactive Forms';
- }
Working with FORMCONTROL Class
The FormControl class takes three parameters as input :
- Initial data value
- Validators (synchronous)
- Validators (Asynchronous)
We will focus on validations in the latter portion of this article.
- export class AppComponent {
- title = 'Forms';
- email= new FormControl('');
- }
On the template, we can use this FormControl using :
- [FormControl] = "email" type ="text" placeholder="What is your email?">
Working with FormGroup Class
Form Controls comprise to become FormGroup. We can think of a FormControl as a child property of FormGroup. The syntax used for FormGroup is as follows
To use it inside the template
- export class AppComponent {
- title = 'Forms';
- SignIn = new FormGroup({
- email: new FormControl(''),
- pwd: new FormControl('')
- })
- }
- [formControl] = "email" type ="text" class="form-control" placeholder="What is your email?"/>
- [formControl] = "pwd" type ="text" class="form-control" placeholder="What is your password?"/>
Working with FormBuilder Class
To simplify the syntax of FormGroup and FormControl, we use FormBuilder. This helps reduce the length of our code and optimize it.
- constructor(private ff : FormBuilder){
- this.SignIn= this.ff.group({
- email: [null, [Validators.required, Validators.minLength(4)]],
- pwd: [null, [Validators.required, Validators.maxLength(8)]]
- })
- }
Working with FormArray Class
If you want to add fields in the form dynamically with the help of an array, FormArray is used. Like other classes, it is imported in the component like this :
To use it inside the component
- import {FormArray} from '@angular/forms';
On the view
- this.SignIn = this.ff.group({
- email: '',
- pwd: ''
- items: this.ff.array([ this.crItem() ])
- });
formArrayName="items"- *ngFor="let item of SignIn.get('items').controls; let count = index;">
[formGroupName]="count">- formControlName="email" ">
- formControlName="password" >
Validations
Till now, we did not add any validation checks to our elements, however, we can do that using Validators in Angular Forms.
- import { FormGroup, FormControl, Validators } from '@angular/forms';
Let us try adding validation to the email field that we created. Inside the component class
- ngOnInit() {
- this.loginForm = new FormGroup({
- email: new FormControl(null, [Validators.required]),
- password: new FormControl(null, [Validators.required, Validators.maxLength(8)]),
- class: new FormControl(null)
- });
- }
On the template
- <input formControlName="email" type="text" class="form-control" placeholder="Enter Email" />
- <div class="alert alert-danger" *ngIf="loginForm.get('email').hasError('required') && loginForm.get('email').touched">
- Email is required
- </div>
- <input formControlName="password" type="password" class="form-control" placeholder="Enter Password" />
- <div class="alert alert-danger" *ngIf="!loginForm.get('password').valid && loginForm.get('email').touched">
- Password is required and should less than or equal to 8 characters
- </div>
This will give output as :

Creating a Reactive Form
Step 1 :Import ReactiveFormsModule in App Module
Step 2 :Import FormControl, FormGroup classes in the component class
Step 3 : Create a FormGroup class with details like email, password
Step 4 : On the template, create a Submit button with the function to implement submit in the class.
Putting together everything
On the browser
- import { Component, OnInit } from '@angular/core';
- import { FormGroup, FormControl, FormArray, Validators } from '@angular/forms';
- @Component({
- selector: 'app-root',
- template:`
- <div class="container">
- <br />
- <form (ngSubmit)='loginUser()' [formGroup]='loginForm' novalidate class="form">
- <input formControlName='email' type="text" class="form-control" placeholder="Enter Email" />
- <div class="alert alert-danger" *ngIf="loginForm.get('email').hasError('required') && loginForm.get('email').touched">
- Email is required
- </div>
- <input formControlName='password' type="password" class="form-control" placeholder="Enter Password" />
- <div class="alert alert-danger" *ngIf=" !loginForm.get('password').valid && loginForm.get('email').touched">
- Password is required and should less than or equal to 8 characters
- </div>
- <button [disabled]='loginForm.invalid' class="btn btn-default">Login</button>
- </form>
- </div>
- `
- })
- export class AppComponent implements OnInit {
- loginForm: FormGroup;
- ngOnInit() {
- this.loginForm = new FormGroup({
- email: new FormControl(null, [Validators.required, Validators.minLength(4)]),
- password: new FormControl(null, [Validators.required, Validators.maxLength(8)])
- });
- }
- loginUser() {
- console.log(this.loginForm.status);
- console.log(this.loginForm.value);
- }
- }

Creating Custom Validations for Angular Reactive Forms
Now that we have applied validation to email and password, for class we want to create a validation for range such that the class should be from 1 to 12 only. In this case, we will have to write a custom validator as Angular doesn’t provide range validation.So for that, we need to create a function that takes one input parameter of type AbstractControl and returns an object of key value pair in case the validation fails.
- function classValidator(control: AbstractControl) : {[key : string] : boolean} | null {
- return null;
- }
Here we have created a custom validator named classValidator where the user will be able to enter a class only if it’s in the range that we have provided it. In case of failure of validation, it will return an object which contains key value pair.
In the component class
- class: new FormControl(null, [classValidator])
On the Template, it goes like :
display
- <input formControlName='Class' type="number" class="form-control" placeholder="Enter Class" />
- <div class="alert alert-danger" *ngIf="loginForm.get('class').dirty && loginForm.get('class').errors && loginForm.get('class’).errors.classRange ">
- Class should be in between 1 to 12
- </div>

This is how Custom validators help us put validation to our form controls.
SUMMARY
In this article, we discussed what are Reactive Forms in Angular. We also saw some of the building blocks of reactive forms and that why reactive forms are beneficial to use. We also created a basic reactive form with some built-in validations in it. Then we created our own custom class validator and applied it to the form.
Comments
Post a Comment