In Angular, there are two types of forms Template-driven form and Reactive form. Template-driven forms are mostly used in the small and static types of forms on the other hand Reactive forms are most suitable for getting dynamic inputs from the user with custom validations.
Reactive forms are one of the key features of Angular forms. Because of its capabilities and versatile nature. The reactive form follows a model-driven approach for handling dynamic inputs of the form. You can create multiple form controls in the group, validate values of form, and create a dynamic form where you can update or remove controls at runtime
Reactive Forms are ideal for complex procedures with a number of inputs, complex validation rules, or dynamic interactions between form elements and users.
Using reactive forms in Angular involves several steps. Here's a basic guide to get you started:
In your Angular module (usually app.module.ts), import ReactiveFormsModule from @angular/forms
import { ReactiveFormsModule } from '@angular/forms';
@NgModule({
imports: [
// Other imports...
ReactiveFormsModule
],
// Other configurations...
})
export class AppModule { }
In your component file (e.g., app.component.ts), import FormGroup and FormControl from @angular/forms to create a form group
import { Component } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
myForm: FormGroup;
constructor() {
this.myForm = new FormGroup({
// Define your form controls here
firstName: new FormControl(''),
lastName: new FormControl(''),
email: new FormControl('')
});
}
onSubmit() {
// Handle form submission here
console.log(this.myForm.value);
}
}
In your component's HTML file (e.g., app.component.html), bind form controls using the formControlName directive and handle form submission:
<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
<label for="firstName">First Name:</label>
<input type="text" id="firstName" formControlName="firstName">
<label for="lastName">Last Name:</label>
<input type="text" id="lastName" formControlName="lastName">
<label for="email">Email:</label>
<input type="email" id="email" formControlName="email">
<button type="submit">Submit</button>
</form>
You can add validation rules to form controls by passing validators to the FormControl. For example, to make the email address field required and validate its format, you can modify the form creation code like this:
import { Validators } from '@angular/forms';
Testing Support:
constructor() {
this.myForm = new FormGroup({
firstName: new FormControl(''),
lastName: new FormControl(''),
email: new FormControl('', [Validators.required, Validators.email])
});
}
Then, in your post HTML, you can display error messages for the email field if it's invalid
<div *ngIf="myForm.get('email').invalid && myForm.get('email').touched">
<div *ngIf="myForm.get('email').errors.required">Email is required.</div>
<div *ngIf="myForm.get('email').errors.email">Invalid email format.</div>
</div>
These steps cover the basics of using reactive forms in Angular. You can further explore features like form arrays for dynamic forms, custom validators, and more as your application requirements grow.
Reactive forms in Angular offer several powerful features that make form handling more robust and flexible compared to template-driven forms. Here are some key features of reactive forms:
Reactive forms follow a model-driven approach where the building of form structure, data about form, and validation is provided in component class rather than defined it directly in the template. This separation keeps the template clean and focused on presentation only. Various advantages are using a model-driven approach these listed out below
More Control: You have more control over the form controls and their validations.
Reusability: Forms built using this approach can be reused in different components or in different interfaces.
In reactive forms, you can define the form structure explicitly using Typscript classes and objects which includes creating form groups, form controls, form arrays or nested form arrays provides better control on complicated form layouts. Overall, you can control reactive form explicitly through typescript.
Reactive forms support dynamic form creation and manipulation. You can add or remove form controls, form groups, or form arrays programmatically based on future user interactions or data requirements, making it easier to handle dynamic UIs.
Reactive forms provide built-in validation mechanisms that allow you to define validation rules such as required fields, minimum and maximum lengths, pattern-based validation, custom validators, and asynchronous validators. Validation status can be easily checked and displayed in the UI.
You can track changes to the world's form values and status (pristine, dirty, touched, untouched) using observables. This enables you to react to form changes in real time, perform validation as the user interacts with the form, and implement custom logic based on form status.
Reactive forms use FormGroup and FormControl classes to represent form elements. A FormGroup encapsulates a collection of form controls, while a FormControl represents an individual form element or control (input, select, textarea, etc.). This hierarchical structure supports organizing and managing form data effectively.
FormArray is used to handle the controls dynamically and store all the controls in one unit like Array or List. FormArray is a collection of Controls like formControl, formGroup, or another formArray and we can able to add, remove, and manipulate these controls dynamically. We can implement this functionality by using the FormArray class provided by ' @angular/forms'.
skills: new FormArray([new FormControl(null, Validators.required)])
Here skills is one formArray contains a list of controls.
addskills() {
(<FormArray>this.myReactiveForm.get('skills')).push(
new FormControl(null, Validators.required)
);
}
The push method of Array is used to insert new form control in FormArray. In the above example, We have created one new formControl with its fields and validation and then added this control to the form array using the push method.
Reactive forms offer robust error handling and display capabilities. Reactive forms contain one method hasError is used to check whether a specific control contains the errors or not. You can easily apply the CSS classes on UI or apply validation errors by checking the control status (valid, invalid, pristine, dirty).
myForm!: FormGroup
this.myForm = this.formBuilder.group({
name: ['', [Validators.required,Validators.minLength(15)]],
});
<form [formGroup]="myForm">
<div formGroupName="userdetails">
<label class="form-label">username</label>
<input type="text" formControlName="username"/>
<div *ngIf="!myForm.get('name')?.valid">
<small *ngIf="myForm.get('name')?.hasError('required')">
name required</small>
<small *ngIf="myForm.get('name')?.hasError('minlength')">
minimum length should be 15
</small>
</div>
</div>
</form>
Since reactive forms rely on RxJS observables for tracking form changes, you can integrate form handling seamlessly with other asynchronous operations, such as fetching data from APIs, handling user authentication, or performing form submissions with reactive HTTP requests.
Reactive forms are testable, allowing you to write unit tests and integration tests for form validation, user interactions, form submission, and error handling. Angular's testing utilities and tools make it easier to test reactive forms in isolation or within components.
These features collectively make reactive forms a powerful choice for building complex and interactive forms in Angular applications, especially when dealing with dynamic data, validation requirements, and asynchronous operations.
Best practices to enhance and maintain angular forms are as follows:
FormBuilder is a class provided by '@angular/forms' to create forms in angular. It accepts one object as an argument. An object contains all the form controls or form fields along with validations. When creating complicated forms, FormBuilder can save you a lot of time & effort.
//registrationForm.component.ts
import { FormBuilder } from '@angular/forms';
@Component({
selector: 'registration-form',
templateUrl: './registrationForm.component.html',
})
export class RegistrationComp {
registrationForm:any;
constructor(private formBuilder: FormBuilder) {
this.registrationForm = this.formBuilder.group({
name: [''],
email: [''],
city:[''],
});
}
}
In the above code snippet, registrationForm is created using the FormBuilder class which is provided by '@angular/forms', we are required to provide one object to the FormBuilder Class and that object contains all the form controls in it.
Angular has multiple built-in string validators but for certain conditions, they are not compatible. Therefore you must use a custom validator as per your need or condition to keep your code maintainable and reusable.
Instead of subscribing observables in the template you can use an async pipe to subscribe handle subscription and unsubscription and ensure that it always displays an updated value in line with a template or most recent data. With technology such that, you can enhance performance and make debugging easier
Getters methods are used to access the form controls, formGroup, or FormArray easily. Use of getters method makes your code more modular & testable.
get name() {
return this.registrationForm.get('name') as FormControl;
}
get email() {
return this.registrationForm.get('email') as FormControl;
}
In the above code snippet, there are two getter methods name() and email(), Which are used to return specific form fields as one form control.
Without directly using ai or modifying the control value property, you can use the setValue() or patchValue() methods to update values for form controls. By using it, It ensures that the form is correctly updated and related validations errors can be handled correctly.
If you want to update all form fields, use setValue; if you're going to update specific form fields, use the patchValue method.
UpdateAllFields() {
this.registrationForm.setValue({
name: 'Aniket',
email: 'aniket@example.com',
city:'pune',
});
}
In the above example, setValue is used to update all fields of registrationForm. we are required to provide all fields otherwise It will throw an error.
UpdateSpecificFields() {
this.registrationForm.patchValue({
name: 'Aniket',
city:'pune',
});
}
patchValue() function is used when we want to update only specific fields of the form. like setValue it will not throw an error if we do not provide all fields.
If you are using template-driven form for simpler and smaller form inputs then of course you can still use reactive forms directive in it to add validations and other features to your form.
Use resetForm() method when you want to clear form input. For example, after submitting the form we want to restore the form at its initial values in this case we can use resetForm() method.
Using the above best practices you can easily build a Reactive form with better performance, maintainability, and flexible controls this eventually enhances the user experience.
Reactive forms are widely used by developers in angular to build forms. Reactive forms are more maintainable, versatile, and reliable as compared to Template-driven forms. Overall, reactive forms can enhance performance, manage dynamic data, validate them, handle form submissions, and much more. Hence reactive form is the most powerful feature of angular to create a form.
This website uses cookies to analyze website traffic and optimize your website experience. By continuing, you agree to our use of cookies as described in our Privacy Policy.