Reactive Forms In Angular

Reactive Forms In Angular

One of the two ways to design Angular forms is with reactive forms (also known as model-driven forms). In this article, we will learn how to create a simple Example of Reactive Form. To create reactive forms, we must first import the ReactiveFormsModule. We then use Form Group, Form Control, and Form Arrays to generate the Form Model in the component class. The HTML form template will then be created and bound to the Form Model.

What is Reactive Forms?

Reactive forms are those in which the form's structure is defined in the component class. Form GroupForm Control, and Form Arrays are used to build the form model. The validation rules are also defined in the component class. Then, in the template, we bind it to the HTML form. This differs from template-driven forms, in which the logic and controls are defined in the HTML template.

How to use Reactive Forms

  • ReactiveFormsModule should be imported.
  • Using Form GroupForm Control, and Form Arrays, create a Form Model in a component class.
  • Make an HTML form that looks like the Form Model.
  • Create a link between the HTML form and the Form Model.

Reactive Forms Example Application

To create a new application, use ng new command.

ng new reactive-forms  --routing=true --style=css

Import ReactiveFormsModule

The ReactiveFormsModule must be imported before we can work with reactive forms. We normally import it into a root or common module. All of the form directives and constructs for working with angular reactive forms are contained in the ReactiveFormsModule.
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
 
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
 
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    ReactiveFormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Model

On the HTML components in the template-driven method, we used the ngModel & ngModelGroup directives. The FormGroup and FormControl instances were built by the FormsModule using the template. This occurs in the background.

It is our obligation to design the Model using FormGroupFormControl, and FormArray in the Reactive Forms methodology.

The three-building components of Angular Forms are FormGroupFormControl, and FormArray. In the Angular Forms Tutorial, we learned about them.

The state of a single form element in our form is encapsulated by FormControl. It saves the form element's value and state and allows us to interact with it via properties and methods.

FormGroup is a container for a group of form controls. It can also include form arrays and form groups. An angular form is, in fact, a FormGroup.

Let's make it happen.
import { FormGroup, FormControl, Validators } from '@angular/forms'

FormGroup

The FormGroup is constructed using the syntax below.
contactForm = new FormGroup({})

There are three arguments to the FormGroup. A child FormControl, a validator, and an asynchronous validator are all included in this collection. Validators are not required.

FormControl

The collection of FormControlis the first argument to FormGroup. The FormControl method is used to add them, as seen below.
contactForm = new FormGroup({
  firstname: new FormControl(),
  lastname: new FormControl(),
  email: new FormControl(),
  gender: new FormControl(),
  isMarried: new FormControl(),
  country: new FormControl()
})

We've built a FormGroup instance and named it contactForm in the code above. Our top-level FormGroup is contactForm. We have five FormControl instances under the contactForm, each representing the variables firstname, lastname, email, gender, ismarried, and country.

Sync Validator and Async Validator are the other two arguments to FormGroup. They aren't required.

HTML Form

The following step is to create an HTML form. A standard HTML form is shown below. A <form> tag is used to encapsulate it. We've included two text fields (FirstName and LastName), an email field, a gender radio button, an isMarried checkbox, and a picklist (country). This is a list of Form elements.
<form">
 
  <p>
    <label for="firstname">First Name </label>
    <input type="text" id="firstname" name="firstname">
  </p>
 
  <p>
    <label for="lastname">Last Name </label>
    <input type="text" id="lastname" name="lastname">
  </p>
 
  <p>
    <label for="email">Email </label>
    <input type="text" id="email" name="email">
  </p>
 
  <p>
    <label for="gender">Geneder </label>
    <input type="radio" value="male" id="gender" name="gender"> Male
    <input type="radio" value="female" id="gender" name="gender"> Female
  </p>
 
  <p>
    <label for="isMarried">Married </label>
    <input type="checkbox" id="isMarried" name="isMarried">
  </p>
 
  <p>
    <label for="country">country </label>
    <select id="country" name="country">
      <option [ngValue]="c.id" *ngFor="let c of countryList">
        {{c.name}}
      </option>
    </select>
  </p>
 
  <p>
    <button type="submit">Submit</button>
  </p>
 
</form>

Binding the template to the model

Now it's time to link our model to the Template. We need to tell Angular that the form has a model.

The FormGroup directive is used to accomplish this, as illustrated below.
<form [formGroup]="contactForm">

We've wrapped the FormGroup directive in a square bracket (one-way binding) and set it equal to the model.

After that, we must tie form fields to FormControl objects. For this, we use the FormControlName directive. This directive is applied to each form field element in our form. The name of the appropriate FormControl instance in the component class is set as the value.
<input type="text" id="firstname" name="firstname" formControlName="firstname">
<input type="text" id="lastname" name="lastname" formControlName="lastname">

Submit form

Using the Angular directive ngSubmit, we send the form data to the component. Please note that our form already has a submit button. The ngSubmit directive attaches itself to the submit button's click event. To connect ngSubmit to the OnSubmit method, we use event binding (parentheses). When the user clicks the submit button, ngSubmit calls the Component class's OnSubmit function.
<form [formGroup]="contactForm" (ngSubmit)="onSubmit()">

The following code is final code of the app.component.html file.
<form [formGroup]="contactForm" (ngSubmit)="onSubmit()">
 
  <p>
    <label for="firstname">First Name </label>
    <input type="text" id="firstname" name="firstname" formControlName="firstname">
  </p>
 
  <p>
    <label for="lastname">Last Name </label>
    <input type="text" id="lastname" name="lastname" formControlName="lastname">
  </p>
 
  <p>
    <label for="email">Email </label>
    <input type="text" id="email" name="email" formControlName="email">
  </p>
 
  <p>
    <label for="gender">Geneder </label>
    <input type="radio" value="male" id="gender" name="gender" formControlName="gender"> Male
    <input type="radio" value="female" id="gender" name="gender" formControlName="gender"> Female
  </p>
 
  <p>
    <label for="isMarried">Married </label>
    <input type="checkbox" id="isMarried" name="isMarried" formControlName="isMarried">
  </p>
 
  <p>
    <label for="country">country </label>
    <select id="country" name="country"  formControlName="country">
      <option [ngValue]="c.id" *ngFor="let c of countryList">
        {{c.name}}
      </option>
    </select>
  </p>
 
  <p>
    <button type="submit">Submit</button>
  </p>
 
</form>

Receive the data in the Component class

The final step is for the component class to accept the form data. We simply need to add an onSubmit method to our component class.
onSubmit() {
  console.log(this.contactForm.value);
}

To communicate the value of our form data to the console window, we use console.log(this.contactForm.value).

Test the form

Now you may test the app and see what happens. View the value produced by contactForm.value in the developer console. The form's values are delivered as a JSON object, which you can use to provide to your backend API to save the data to the database.

FormControl

There are three arguments to a FormControl. A validator, a default value, and an asynchronous validator are all included. They are all optional.

Default Value

A default value can be specified as a string or as a key-value pair object. You can set both the value and whether or not the control is disabled when you pass object.
//Setting Default value as string
firstname= new FormControl(‘Sachin’);

//Setting Default value & disabled state as object
firstname: new FormControl({value: ‘Rahul’, disabled: true}),

Sync Validator

The array of sync Validators is the second parameter. Required and minLength, for example, are built-in Validators in Angular.

As seen below, you can use the Validator function to pass.
firstname: new FormControl('', [Validators.required,Validators.minLength(10)]),

Asynchronous validator

The Async Validator is the third argument. Async Validators have a similar syntax to Sync Validators.

In our upcoming article, Validations in Reactive Forms, we will go over more about validation.

Grouping the controls using FormGroup

Various form controls can be grouped together. Fields like street, city, and pincode, for example, will each have their own form control, but they can be combined together as an address form group.
contactForm = new FormGroup({
  firstname: new FormControl(),
  lastname: new FormControl(),
  email: new FormControl(),
  gender: new FormControl(),
  isMarried: new FormControl(),
  country: new FormControl(),
  address:new FormGroup({
    city: new FormControl(),
    street: new FormControl(),
    pincode:new FormControl()
  })
})

We built a new FormGroup Address and added three form controls, namely city, street, and pincode, in the code above.

Use the formGroupName directive in the template to encapsulate the control with a div element, as seen below.
<div formGroupName="address">

  <div class="form-group">
      <label for="city">City</label>
      <input type="text" class="form-control" name="city" formControlName="city" >
  </div>

  <div class="form-group">
      <label for="street">Street</label>
      <input type="text" class="form-control" name="street" formControlName="street" >
  </div>

  <div class="form-group">
      <label for="pincode">Pin Code</label>
      <input type="text" class="form-control" name="pincode" formControlName="pincode">
  </div>

</div>

Conclusion

In this article, we learned how to create Angular Reactive Forms. We will add validation rules to our application in the upcoming article.

I hope this article helps you and you will like it.👍

If you have any doubt or confusion then free to ask in comment section.

Post a Comment

Previous Post Next Post