Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Reactive Forms in Angular

DZone's Guide to

Reactive Forms in Angular

In this post, a developer explores what reactive forms are and how to validate reactive forms in Angular. Read on to learn more!

· Web Dev Zone ·
Free Resource

Deploying code to production can be filled with uncertainty. Reduce the risks, and deploy earlier and more often. Download this free guide to learn more. Brought to you in partnership with Rollbar.

As we saw in the last article, there are two types of form development approaches that we can use in Angular. The first one is template-driven development and the other is the reactive forms approach. Let's explore what reactive forms are and how to validate reactive forms in Angular.

What Are Reactive Forms?

This approach uses the reactive form of developing the forms that favor the explicit management of data between the UI and the model. With this approach, we create a tree of Angular form controls and bind them in the native form controls. As we can create the forms control directly in the component, it makes it a bit easier to push the data between the data models and the UI elements.

Initial Imports for Using Reactive Forms

To begin using the reactive forms, we must ensure that we are importing the proper references in the project and at the right location. Before we start, let’s add the new component using the ng g c [name of component] command in the command prompt. In this, I have added the component to my code, and the name of the component is ReactiveDemoComponent

Okay, after adding the component, the first import we need is our bootstrap module or application module (i.e. app.module.ts) code snippet for that is:

import { BrowserModule } from '@angular/platform-browser';  
import { NgModule } from '@angular/core';  
import {ReactiveFormsModule} from '@angular/forms'  
import { AppComponent } from './app.component';  
import { ReactiveDemoComponent } from './reactive-demo/reactive-demo.component';  

@NgModule({  
  declarations: [  
    AppComponent,  
    ReactiveDemoComponent  
  ],  
  imports: [  
    BrowserModule,  
    ReactiveFormsModule  
  ],  
  providers: [],  
  bootstrap: [AppComponent]  
})  
export class AppModule { }  

In this, we have imported the ReactiveFormsModule and added that module in the imports array.

The next change we need to make is to the component where we are doing the change. We need to simply add these three packages into the import section.

import { Component, OnInit } from '@angular/core';  
import {FormGroup,FormControl,FormBuilder} from '@angular/forms'  
@Component({  
  selector: 'app-reactive-demo',  
  templateUrl: './reactive-demo.component.html',  
  styleUrls: ['./reactive-demo.component.css']  
})  
export class ReactiveDemoComponent implements OnInit {  
                   constructor() { }  
                  ngOnInit() {}}  

To sum up, we have two basic steps:

  1. Import ReactiveFormsModule in the application Module and add it in the import array.
  2. Import the FormGroupFormControl, and FormBuilder classes to the component.

FormControl

It tracks the value of the controls and validation of the individual control in the form.

FormGroup

Tracks the validity and state of the FormControl instance or, moreover, we can make FormGroup a collection of FormControl.

FormBuilder

This helps us to develop the form along with its initial value and validations.

Designing the Component Code

Now that we know the basics of the FormControlFormGroup, and FormBuilderlet's design the form.

import { Component, OnInit } from '@angular/core';  
import {FormBuilder,FormGroup,FormControl,Validators,NgForm} from '@angular/forms'  
@Component({  
  selector: 'app-reactive-demo',  
  templateUrl: './reactive-demo.component.html',  
  styleUrls: ['./reactive-demo.component.css']  
})  
export class ReactiveDemoComponent implements OnInit {  
signupForm:FormGroup;  
FirstName:string="";  
LastName:string="";  
Email:string="";  
Password:string="";  
constructor(private frmbuilder:FormBuilder)  
   {  

    this.signupForm=frmbuilder.group({  
    fname:new FormControl(),  
    lname:new FormControl(),  
    Emailid:new FormControl(),  
    userpassword:new FormControl()  
    });  
   }  
  ngOnInit() {  
  }  
  PostData(signupForm:NgForm)  
  {  
    console.log(signupForm.controls);  
  }  

}  

In the above code, we have designed our form in the component as we know that in the reactive forms approach we design the forms in the template and then do the bindings for the HTML.

What we have done in this code is:

  1. Declared the FormGroup property and named it signupForm in the component.

  2. In the constructor, we are using dependency injection to use  FormBuilder

    1. this..group(Formcontrols collection): This line of code takes the  Formcontrols collection and groups into the FormBuilder.

  3. The next portion is to define the controls in the FormBuilder and group them to assign It to the signupForm form:

    1.    fname:new FormControl(),

Here we are declaring the fname to be of type FormControl() and assigning to the fname property which will be our form control name in the HTML. Here we can specify the initial value of our form controller and add some validators in it (we will see that in the next section).

Now it’s time to tie up these controls in the component to our template via our HTML. How we can do this? Let’s just check it out:

<div>  
  <form [formGroup]='signupForm' (ngSubmit)="PostData(signupForm)">  
      <div class="form-container">  
          <div class="row columns">  
   <div>  
    <input type="text" formControlName='fname' placeholder="Your First name">  
    </div>  
    <div>  
    <br>  
    <input type="text" formControlName='lname' placeholder="Your Last name">  
  </div>  
    <br>  
    <div><input type="text" formControlName='Emailid' placeholder="Your Email id"></div>  
    <br>  
    <div>  
    <input type="Password" formControlName='userpassword' placeholder="Your password">  
  </div>  
  <br>  
  <div>  
<input type="Submit" value="Post Data" >  
  </div>  
  </div>  
  </div>  
  </form>  
</div>  

In these two things, we have to keep the following in mind in order to understand how binding of the controls takes place:

 <form [formGroup] (ngSubmit)="PostData(signupForm)">

In the above code, we are binding the signupForm to the formGroup directive.

  • Now that we have linked the signupForm to the formGroup, we can access the FormControl values inside the template.
  •     <input type="text" placeholder="Your First name">
    •  We have used the formControlName directive to map the element in the template to the property in the component.
  • We are using the Angular NgSubmit directive to the post data method in the component which will be called on the Button click, which logs all the values of the Form Controls into the template.

Validations With Reactive Forms

Now, the most important part of any form is to add the validations in the application. Let’s see how we can add the validation in the form. To do that, let's check the FormControl in the component.

When we use fname:new FormControl(), the first argument in FormControl is the initial value and the second value is the validations that we can add there.

The only change in the component would look like below:

this.signupForm= frmbuilder.group({  
  fname:['',Validators.compose([Validators.required,Validators.maxLength(15),Validators.minLength(1)])],  
  lname:['',[Validators.required,Validators.maxLength(19)]],  
  Emailid:['',[Validators.required,Validators.email]],  
  userpassword:['',Validators.required]  
})  

Here we are adding the Validators for the fields in the application. As we know there can be more than one validation for the controls, we can add them in two ways. First, for single validations, we can use single validators and for the multiple validations we can use Validators.compose (list of validators separated by ,).

Showing the Error Message

<div>  
  <form [formGroup]='signupForm' (ngSubmit)="PostData(signupForm)">  
      <div class="form-container">  
          <div class="row columns">  
   <div>  
    <input type="text" formControlName='fname' name='fname' id='fname' placeholder="Your First name">  

    <div *ngIf="signupForm.controls['fname'].touched && !signupForm.controls['fname'].valid">  
        <span *ngIf="signupForm.controls['fname'].hasError('required') ">  
            First name is required  
            </span>  
            <span *ngIf="signupForm.controls['fname'].hasError('minlength') ">  
             Min length is 1  
            </span>  
            <span *ngIf="signupForm.controls['fname'].hasError('maxlength') ">  
            max length is 15  
        </span>  
    </div>  
    </div>  
    <div>  
    <br>  
    <input type="text" formControlName='lname' placeholder="Your Last name">  

    <div *ngIf="signupForm.controls['lname'].touched && !signupForm.controls['lname'].valid">  
        <span *ngIf="signupForm.controls['lname'].hasError('required') ">  
            Last name is required  
            </span>  
            <span *ngIf="signupForm.controls['lname'].hasError('minlength') ">  
             Min length is 1  
            </span>  
            <span *ngIf="signupForm.controls['lname'].hasError('maxlength') ">  
            max length is 15  
        </span>  
    </div>  
  </div>  
    <br>  
    <div><input type="text" formControlName='Emailid' placeholder="Your Email id"></div>  
    <div *ngIf="signupForm.controls['Emailid'].touched && !signupForm.controls['Emailid'].valid">  
        <span *ngIf="signupForm.controls['Emailid'].hasError('required') ">  
           Email ID is needed  
             </span>  

      <span *ngIf="signupForm.controls['Emailid'].hasError('email') ">  
           Invalid Email ID  
            </span>  

    </div>  
    <br>  
    <div>  
    <input type="Password" formControlName='userpassword' placeholder="Your password">  
  </div>  
  <br>  
  <div>  
<input type="Submit" value="Post Data" [disabled]='!signupForm.valid' >  
  </div>  
  </div>  
  </div>  
  </form>  
</div>

In the above code snippet, we are showing the error messages when the field is touched and a value is entered:  

<div *ngIf="signupForm.controls['fname'].touched && !signupForm.controls['fname'].valid">  
     <span *ngIf="signupForm.controls['fname'].hasError('required') ">  
         First name is required  
         </span>  
         <span *ngIf="signupForm.controls['fname'].hasError('minlength') ">  
          Min length is 1  
         </span>  
         <span *ngIf="signupForm.controls['fname'].hasError('maxlength') ">  
         max length is 15  
     </span>    </div>  

Here, we have listed all the validators that we have applied in the component. To check if the control is failing any validation, we have added the following code:

<div *ngIf="signupForm.controls['fname'].touched && !signupForm.controls['fname'].valid">

This div will be displayed only if the fname is touched and it is valid.

In that div, we have other sections to display the errors such as required and min length and max length. We use the ngIf directive here to display the proper error messages.

This was reactive forms and validating reactive forms.

Deploying code to production can be filled with uncertainty. Reduce the risks, and deploy earlier and more often. Download this free guide to learn more. Brought to you in partnership with Rollbar.

Topics:
web dev ,angular ,reactive forms ,tutorial

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}