As an Angular developer, managing forms can sometimes be a daunting task, especially when using ngValueAccessor. While ngValueAccessor is powerful, it often requires implementing numerous functions to handle value retrieval and updates for our form elements. Recently, I transitioned to using FormGroupDirective, and it has significantly streamlined the process. Here’s why this switch was a game-changer for me and my team:
Why FormGroupDirective?
Simplicity in Implementation
With FormGroupDirective, much of the boilerplate code required by ngValueAccessor is eliminated. This means less time writing repetitive code and more time focusing on business logic.Better Synchronization of Values
FormGroupDirective automatically synchronizes values, so there’s no need to write additional functions for value retrieval and setting. This makes the code cleaner and easier to maintain.Improved Code Readability
Code written with FormGroupDirective is significantly more readable and understandable. This is especially beneficial for the entire development team, including newcomers.Greater Flexibility
Using FormGroupDirective provides more flexibility in managing forms, allowing us to easily handle more complex forms.
Let's dive into a practical example to illustrate how FormGroupDirective can simplify form management.
Before: Using ngValueAccessor
import { Component, forwardRef } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
@Component({
selector: 'app-custom-input',
template: `
<input type="text" [value]="value" (input)="onInput($event.target.value)" />
`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CustomInputComponent),
multi: true,
},
],
})
export class CustomInputComponent implements ControlValueAccessor {
value: string;
onChange: any = () => {};
onTouched: any = () => {};
writeValue(value: any): void {
this.value = value;
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
onInput(value: string) {
this.value = value;
this.onChange(value);
}
}
After: Using FormGroupDirective
import { Component, Input } from '@angular/core';
import { FormGroup, FormGroupDirective, ReactiveFormsModule } from '@angular/forms';
@Component({
selector: 'app-custom-form',
template: `
<form [formGroup]="form">
<input [formControlName]="controlName" />
</form>
`,
standalone:true,
imports:[ReactiveFormsModule]
})
export class CustomFormComponent {
form!: FormGroup;
@Input({ required: true }) controlName!: string
constructor(private _rootFormGroup: FormGroupDirective,) {
this.form = this._rootFormGroup.control as FormGroup;
}
}
Top comments (2)
Hi Amin-Karimi,
Top, very nice and helpful !
Thanks for sharing.
Hi João Angelo,
Thank you! I'm glad you found it helpful.