Reactive Form in angular

Reactive Form in angular

Reactive Form in angular

In this article, I will guide you about reactive forms. When to use reactive forms? And features of reactive form also show some example of reactive forms.


Reactive Forms Features:

  • More flexible, but required advance knowledge.
  • Handles any complex scenarios
  • No data binding is done (immutable data model preferred by most developers)
  • More component code and less HTML markup
  • Handling an event based on a debounce time
  • Handling events when the components are distinct until changed
  • Adding elements dynamically
  • Easier unit testing
  • Reactive are validated via function
  • Data model is structured
  • predictability in Reactive form is Synchronous.
  • The form value would be available in two different places: the view model and the FormGroup
  • Use of Observables for reactive programming
  • The form value would be available in two different places: the view model and the FormGroup
  • complex validation logic is actually simpler to implement
  • Can generally used for large-scale applications


When to use Reactive Forms:

If forms are very important for your app, or reactive pattern are used in your app, you should use reactive forms.

Note:if your using reactive form also import FormModule and ReactiveFormModule in appmodule or specific component module.

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,
    FormModule,
    ReactiveFormsModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Characteristic of Reactive Forms

  • FormControl Each input element in the form is ‘FormControl’. The ‘FormControl’ tracks the value and validation status of form fields.
  • FormGroup Track the value and validate the state of the group of ‘FormControl’.
  • FormBuilder Angular service which can be used to create the ‘FormGroup’ or FormControl instance quickly.
  • Form Array That can hold infinite form control, this helps to create dynamic forms.


Form With FormGroup Characteristic:

export class FormComponent {
  profileForm = new FormGroup({
    email: this.emailFormControl, 
    firstName: new FormControl(''),
    lastName: new FormControl(''),
    address: new FormGroup({
      street: new FormControl(''),
      city: new FormControl(''),
      state: new FormControl(''),
      zip: new FormControl('')
    })
  });
}

Output with Json Format

{
    email: '', 
    firstName: '',
    lastName: '',
    address: {
      street: '',
      city: '',
      state: '',
      zip: ''
  }
}

FormBuilder:

The FormBuilder service is an injectable provider that is provided with the reactive forms module. form builder is a service that does the same things as form-group, form-control and form-array. FormBuilder is a service that is trying to help us reduce boiler-plate code. there is no technical advantage and whichever code you use all boils down to your preference.


Form with FormBuilder Characteristic:

export class FormComponent {
  constructor(private fb: FormBuilder) { }

  profileForm = this.fb.group({
    email: this.emailFormControl,
    firstName: [''],
    lastName: [''],
    address: this.fb.group({
      street: [''],
      city: [''],
      state: [''],
      zip: ['']
    }),
  });
}

Output with Json Format

{
    email: '', 
    firstName: '',
    lastName: '',
    address: {
      street: '',
      city: '',
      state: '',
      zip: ''
  }
}

In which scenarios we can use formgroup or formbuilder?

when our data is dynamic. we should use formbuilder instead of formGroup. because it reduce code boilerplate. and we don't need to write it manually formcontrols.


Example Of FormGroup:

 
<form [formGroup]="singUpForm" (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="country">country </label>
    <select id="country" name="country" formControlName="country">
      <option value="1">India</option>
      <option value="2">USA</option>
      <option value="3">England</option>
      <option value="4">Singapore</option>
    </select>
  </p>
 
 
  <p>
    <button type="submit">Submit</button>
  </p>
 
</form>
import { Component } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms'
 
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'AngularForm';
 
  contactForm = new FormGroup({
    firstname: new FormControl(),
    lastname: new FormControl(),
    email: new FormControl(),
    gender: new FormControl(),
    country: new FormControl()
  })
 
 
  onSubmit() {
    console.log(this.contactForm.value);
  }
}

FormGroup Validation

contactForm = new FormGroup({
    firstname: new FormControl('',Validators.required]),
    lastname: new FormControl('',Validators.required]),
    email: new FormControl('',Validators.required]),
    gender: new FormControl('',Validators.required]),
    country: new FormControl('',Validators.required])
  })

//new FormControl('',Validators.required]),
  first parameter is default value. which is empty string. and second
  parameter is validation.

Example of FormBuilder

<form [formGroup]="myForm" (ngSubmit)="onSubmit(myForm)">
  <div>
    <label>
      Name:
      <input formControlName="name" placeholder="Your name">
    </label>
  </div>
  <div>
    <label>
      Email:
      <input formControlName="email" placeholder="Your email">
    </label>
  </div>
  <div>
    <label>
      Message:
      <input formControlName="message" placeholder="Your message">
    </label>
  </div>
  <button type="submit">Send</button>
</form>
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  myForm: FormGroup;

  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    this.myForm = this.fb.group({
      name: '',
      email: '',
      message: ''
    });
  }

  onSubmit(form: FormGroup) {
    console.log('Valid?', form.valid); // true or false
    console.log('Name', form.value.name);
    console.log('Email', form.value.email);
    console.log('Message', form.value.message);
  }
}

FormBuilder Validation

 ngOnInit() {
    this.myForm = this.fb.group({
      name: ['', Validators.required],
      email: ['', [Validators.required, Validators.email]],
      message: ['', [Validators.required, Validators.minLength(10)]],
    });
  }

Template Validation

<form [formGroup]="myForm" (ngSubmit)="onSubmit(myForm)">
  <div>
    <label>
      Name:
      <input formControlName="name" placeholder="Your name">
    </label>
    <div *ngIf="myForm.get('name').invalid && (myForm.get('name').dirty || myForm.get('name').touched)">
      Please provide a name.
    </div>
  </div>
  <div>
    <label>
      Email:
      <input formControlName="email" placeholder="Your email">
    </label>
    <div *ngIf="myForm.get('email').invalid && (myForm.get('email').dirty || myForm.get('email').touched)">
      Please provide a valid email address.
    </div>
  </div>
  <div>
    <label>
      Message:
      <input formControlName="message" placeholder="Your message">
    </label>
    <div *ngIf="myForm.get('message').invalid && (myForm.get('message').dirty || myForm.get('message').touched)">
      Messages must be at least 10 characters long.
    </div>
  </div>
  <button type="submit" [disabled]="myForm.invalid">Send</button>
</form>

This code checks to see if the user has interacted with the field (dirty or touched). Then, if the value is not passing the validation requirements, it will display the error message.


What is FormArray

The FormArray is a way to manage the collection of Form Controls in Angular. The controls can be a FormGroup, FormControl, or FormArray.

So the idea about formarrray is just like simple array [] and formgroup is just like object {}, that we are using in programing. so inside array we would be element as well as multiple object.


FormGroup:

let userTestStatus: { id: number, name: string }=
    { "id": 0, "name":'Zeeshan' "Available":true };

FormArray

//Example 1
let userTestStatus:[] = ["id","name", "Available" ];

//Example 2
let userTestStatus={
information: [
    { "id": 0, "name":'Zeeshan', "Available":true },
    { "id": 1, "name":'Ahsan' "Ready":false },
    { "id": 2, "name":'Rehan' "Started":true }
]};

Converted into FormArray

//Example 1
userTestStatusForm=new FormArray(["id", "name", "Available"])

//Example 2
userTestStatusForm=new formGroup({

information=new FormArray([

new FormGroup({
id=new FormControl(0)
name=new FormControl('Zeeshan')
Available=new FormControl(true)
}),

new FormGroup({
id=new FormControl(1)
name=new FormControl('Ahsan')
Available=new FormControl(false)    
}),

new FormGroup({
id=new FormControl(2)
name=new FormControl('Rehan')
Available=new FormControl(true)
})

})
])

How to get value from FromArray

Next, a getter method userInfo, which returns the userInfo FormArray from the userTestStatusForm


get userInfo() : FormArray {
  return this.userTestStatusForm.get("information") as FormArray
}

Adding Some thing in FormArray

Now, we need to add a new info to the information FormArray. Since it is an array we can use the push method to add the new info using the the newInfo method. Note that newInfo() method returns a FormGroup. The name of the FormGroup is its Index in the FormArray.

newInfo(): FormGroup {
   return new  FormGroup({
    id=new FormControl(2)
    name=new FormControl('Rehan')
    Available=new FormControl(true)
   })
}
 
addInfo() {
   this.userInfo.push(this.newInfo());
}

Dynamically Removing Information

Use the removeAt method to remove the element from the skills FromArray.

removeInfo(i:number) {
  this.userInfo.removeAt(i);
}

Template

  Skills:
  <div formArrayName="userInfo">
    <div *ngFor="let info of userInfo().controls; let i=index">
      <div [formGroupName]="i">
        {{i}}
        id :
        <input type="text" formControlName="id">
        name:
        <input type="text" formControlName="name">
         Available:
           <input type="text" formControlName="Available">
        <button (click)="removeInfo(i)">Remove</button>
      </div>
    </div>
  </div>

import { Component, ViewChild, ElementRef } from '@angular/core';
import { FormGroup, FormControl,FormArray, FormBuilder } from '@angular/forms'
 
 
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent  {
  
  title = 'FormArray Example in Angular Reactive forms';
 
  skillsForm: FormGroup;
 
  constructor(private fb:FormBuilder) {
 
userTestStatusForm=new formGroup({

information=new FormArray([

new FormGroup({
id=new FormControl(0)
name=new FormControl('Zeeshan')
Available=new FormControl(true)
})
])
})
  
 
 get userInfo() : FormArray {
  return this.userTestStatusForm.get("information") as FormArray
}
 
newInfo(): FormGroup {
   return new  FormGroup({
    id=new FormControl(2)
    name=new FormControl('Rehan')
    Available=new FormControl(true)
   })
}
 
 addInfo() {
   this.userInfo.push(this.newInfo());
}
 removeInfo(i:number) {
  this.userInfo.removeAt(i);
}

}

Share Article:
  • Facebook
  • Instagram
  • LinkedIn
  • Twitter
  • Recent Posts