Angular Reactive Forms Best Practices

    May 15, 20249 min read12765 viewsUpdated:Nov 27, 2024
    Angular Reactive Forms Best Practices

    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.

    How to Use Reactive Form in Angular?

    Using reactive forms in Angular involves several steps. Here's a basic guide to get you started:

    Import ReactiveFormsModule

    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 { }

    Create a Form Group

    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);
      }
    }

    Bind Form Controls in Template

    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>
    

    Validation and Error Handling

    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.

    Features of Reactive form

    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:

    Model-Driven Approach

    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.

    Explicit Form Structure

    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.

    Dynamic Forms

    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.

    Form Validation

    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.

    Value Changes and Status Tracking

    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.

    FormGroup and FormControl

    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

    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.

    Error Handling and Display

    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>

    Integration with Observables

    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.

    Testing Support

    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.

    Our Angular Development Services Made Convenient for You
    The team of experts at Angular Minds, an
    AngularJS development company is competent to make your application most conveniently.

    Best practices to create a reactive form in angular

    Best practices to enhance and maintain angular forms are as follows:

    Use the FormBuilder to create your form model

    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.

    Use a custom validator function for validation logic

    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.

    Avoid subscribing to templates, instead use the async pipe

    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

    Use getters to access controls and groups

    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.

    Use setValue() or patchValue() over direct control manipulation

    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.

    Use reactive form directives with template-driven forms

    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 the resetForm()

    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.

    On the note of Conclusion

    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.

    24
    Share
    Hire Dedicated Angular Developers in US
    Hire Dedicated Angular Developers in US
    From the pool of best developers, hire Angular Developers in 2 days. If you are in doubt, take a 2-week free trial and experience our work and dedication.
    Hire Now

    Related articles

    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.