Angular Reactive Forms


What are reactive forms in Angular?

Reactive forms in Angular are a way to create forms where the form logic is defined in the component class rather than the template. Reactive forms are more powerful and flexible compared to template-driven forms, allowing developers to handle complex form validations, dynamic form controls, and form states. Reactive forms are built using Angular's FormGroup, FormControl, and FormArray classes from the ReactiveFormsModule.


How do you create a basic reactive form in Angular?

To create a basic reactive form, you need to import the ReactiveFormsModule and define the form controls in the component class using FormGroup and FormControl.

Steps to create a basic reactive form:

  1. Import ReactiveFormsModule in the app's module.
  2. In the component, create an instance of FormGroup with form controls using FormControl.
  3. Bind the form in the template using the [formGroup] and formControlName directives.

Example of a basic reactive form:

import { Component } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';

@Component({
  selector: 'app-contact-form',
  templateUrl: './contact-form.component.html'
})
export class ContactFormComponent {
  contactForm = new FormGroup({
    name: new FormControl(''),
    email: new FormControl(''),
  });

  onSubmit() {
    console.log(this.contactForm.value);
  }
}
<form [formGroup]="contactForm" (ngSubmit)="onSubmit()">
  <input type="text" formControlName="name" />
  <input type="email" formControlName="email" />
  <button type="submit">Submit</button>
</form>

In this example, a FormGroup is created in the component with two form controls: name and email. The form is submitted when the user clicks the submit button.


What is FormGroup in Angular?

FormGroup is a class in Angular used to group multiple form controls into a single object. It is used to manage the values and validation state of a form. A FormGroup is a collection of FormControl instances, where each control represents an input field in the form.

Example of a FormGroup:

import { FormGroup, FormControl } from '@angular/forms';

export class ContactFormComponent {
  contactForm = new FormGroup({
    name: new FormControl(''),
    email: new FormControl(''),
  });
}

In this example, a FormGroup is created with two form controls: name and email.


What is FormControl in Angular?

FormControl is a class in Angular used to represent a single form element, such as an input field or a checkbox. It tracks the value, validation, and status of the form field. Each form control is a part of a FormGroup or can be used independently in a reactive form.

Example of a FormControl:

import { FormControl } from '@angular/forms';

export class ExampleComponent {
  nameControl = new FormControl('');
}

In this example, nameControl is a form control that represents an input field for the name.


How do you handle form submission in reactive forms?

Form submission in reactive forms is handled by binding the form's (ngSubmit) event to a method in the component class. The form data is accessed using the value property of the FormGroup.

Example of handling form submission:

export class ContactFormComponent {
  contactForm = new FormGroup({
    name: new FormControl(''),
    email: new FormControl(''),
  });

  onSubmit() {
    console.log('Form submitted:', this.contactForm.value);
  }
}
<form [formGroup]="contactForm" (ngSubmit)="onSubmit()">
  <input type="text" formControlName="name" />
  <input type="email" formControlName="email" />
  <button type="submit">Submit</button>
</form>

In this example, the form is submitted using the ngSubmit event, and the form data is logged to the console using the contactForm.value property.


How do you validate reactive forms in Angular?

In reactive forms, validation is handled by passing validator functions to the form controls when they are created. Angular provides several built-in validators, such as required, minlength, and email, which can be applied directly to form controls.

Example of form validation:

import { FormGroup, FormControl, Validators } from '@angular/forms';

export class ContactFormComponent {
  contactForm = new FormGroup({
    name: new FormControl('', [Validators.required, Validators.minLength(3)]),
    email: new FormControl('', [Validators.required, Validators.email]),
  });

  onSubmit() {
    console.log(this.contactForm.value);
  }
}
<form [formGroup]="contactForm" (ngSubmit)="onSubmit()">
  <input type="text" formControlName="name" />
  <div *ngIf="contactForm.get('name').invalid && contactForm.get('name').touched">
    Name is required and must be at least 3 characters long.
  </div>

  <input type="email" formControlName="email" />
  <div *ngIf="contactForm.get('email').invalid && contactForm.get('email').touched">
    A valid email is required.
  </div>

  <button type="submit" [disabled]="contactForm.invalid">Submit</button>
</form>

In this example, the Validators.required and Validators.minLength validators are applied to the form controls. Error messages are displayed when the form is invalid, and the submit button is disabled if the form is invalid.


What is FormArray in Angular, and how is it used?

FormArray is a class in Angular that allows you to manage an array of form controls. It is useful when you need to dynamically add or remove form controls at runtime, such as when building a form with a variable number of input fields.

Example of using FormArray:

import { FormGroup, FormControl, FormArray } from '@angular/forms';

export class ExampleComponent {
  form = new FormGroup({
    skills: new FormArray([
      new FormControl('Angular'),
      new FormControl('React')
    ])
  });

  get skills(): FormArray {
    return this.form.get('skills') as FormArray;
  }

  addSkill() {
    this.skills.push(new FormControl(''));
  }
}
<form [formGroup]="form">
  <div formArrayName="skills">
    <div *ngFor="let skill of skills.controls; let i = index">
      <input [formControlName]="i" />
    </div>
  </div>

  <button (click)="addSkill()">Add Skill</button>
</form>

In this example, a FormArray is used to manage a dynamic list of skills. New input fields can be added dynamically by clicking the "Add Skill" button.


How do you reset a reactive form in Angular?

In reactive forms, you can reset a form using the reset() method. This method clears all input values and resets the form state (such as touched and dirty) to their initial values.

Example of resetting a reactive form:

<form [formGroup]="contactForm" (ngSubmit)="onSubmit()">
  <input type="text" formControlName="name" />
  <input type="email" formControlName="email" />
  <button type="submit">Submit</button>
  <button type="button" (click)="contactForm.reset()">Reset</button>
</form>

In this example, clicking the "Reset" button will clear all the form fields and reset the form state to its initial values.


How do you dynamically add or remove form controls in a reactive form?

You can dynamically add or remove form controls in a reactive form by using methods like addControl(), removeControl(), or by managing controls in a FormArray.

Example of dynamically adding a control:

export class ExampleComponent {
  form = new FormGroup({
    name: new FormControl(''),
  });

  addEmailControl() {
    this.form.addControl('email', new FormControl(''));
  }

  removeEmailControl() {
    this.form.removeControl('email');
  }
}

In this example, an email field is dynamically added or removed from the form using the addControl() and removeControl() methods.


What is the difference between template-driven forms and reactive forms?

Template-driven forms and reactive forms are two ways to create forms in Angular, but they differ in how the form logic is handled:

  • Template-driven forms: Most of the form logic is defined in the template (HTML). These forms are easier to use for simple forms but provide less control over form states and validation logic.
  • Reactive forms: Form logic is defined in the component class. These forms are more powerful, scalable, and provide better control over form states, dynamic form fields, and validation. Reactive forms are suitable for complex forms.

In summary, reactive forms are more suitable for complex, dynamic forms, while template-driven forms are simpler and easier for basic use cases.


How do you handle custom validation in reactive forms?

To add custom validation to reactive forms, you can create a custom validator function and pass it to the form control or form group when creating the form. The custom validator function should return null if the control is valid, or an error object if the control is invalid.

Example of custom validation:

import { FormGroup, FormControl, Validators } from '@angular/forms';

export class ContactFormComponent {
  contactForm = new FormGroup({
    email: new FormControl('', [Validators.required, this.emailDomainValidator])
  });

  emailDomainValidator(control: FormControl) {
    const email = control.value;
    if (email && email.indexOf('@example.com') === -1) {
      return { emailDomain: true };
    }
    return null;
  }
}
<form [formGroup]="contactForm">
  <input type="email" formControlName="email" />
  <div *ngIf="contactForm.get('email').errors?.emailDomain">Email must be from example.com domain.</div>
</form>

In this example, the custom validator checks if the email domain is example.com. If not, it shows an error message.

Ads