ControlValueAccessor | Angular

When working with Angular forms, we often use standard input elements like and . But what if we need a custom input component that behaves like a native form control? This is where ControlValueAccessor comes in. What is ControlValueAccessor ? ControlValueAccessor is an Angular interface that allows custom form components to integrate with Angular’s form system. It acts as a bridge between the custom component and Angular Forms, ensuring the form can read and update its value correctly. Without ControlValueAccessor, Angular Forms cannot automatically recognize a custom input component as a valid form control. Why Use ControlValueAccessor? By implementing ControlValueAccessor, we can: ✔ Make a custom component behave like a native input field. ✔ Ensure the component updates the form when the user types. ✔ Allow the form to update the component when its value changes externally. ✔ Support Angular’s built-in form validation and status tracking. Example: Custom Input That Trims Spaces Automatically Let’s say we need an input field that removes extra spaces whenever a user types. Step 1: Create the Custom Input Component import { Component, forwardRef } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; @Component({ selector: 'app-trimmed-input', template: ``, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TrimmedInputComponent), multi: true } ] }) export class TrimmedInputComponent implements ControlValueAccessor { value: string = ''; onChange: (value: string) => void = () => {}; onTouched: () => void = () => {}; // When user types, remove spaces and update value onInput(event: Event) { const inputValue = (event.target as HTMLInputElement).value.trim(); this.value = inputValue; this.onChange(this.value); } // Update the component when the form control value changes writeValue(value: string): void { this.value = value ? value.trim() : ''; } // Register function to handle value changes registerOnChange(fn: any): void { this.onChange = fn; } // Register function to handle input focus/touch events registerOnTouched(fn: any): void { this.onTouched = fn; } } Step 2: Use the Custom Component in a Form import { Component } from '@angular/core'; import { FormControl, FormGroup } from '@angular/forms'; @Component({ selector: 'app-root', templateUrl: './app.component.html' }) export class AppComponent { form = new FormGroup({ username: new FormControl('') }); } How It Works The user types text into the field. Any extra spaces are automatically removed before updating the form control. The cleaned value is passed to the Angular form control using onChange(). If the form updates externally, writeValue() ensures that the custom component reflects the latest value. Other Use Cases for ControlValueAccessor ControlValueAccessor is useful for creating: • Number-only inputs (e.g., phone numbers, IDs). • Inputs that automatically format text (e.g., uppercase conversion). • Custom dropdowns or date pickers that work with Angular Forms. Key Takeaways • ControlValueAccessor enables custom components to work with Angular Forms. • It ensures bidirectional communication between the component and the form control. • Implementing it properly improves form validation, value tracking, and user experience. Understanding ControlValueAccessor is crucial for any Angular developer building custom form components. By following the example above, you can create form controls that feel native and integrate seamlessly into your applications.

Mar 18, 2025 - 16:20
 0
ControlValueAccessor | Angular

Image description

When working with Angular forms, we often use standard input elements like and . But what if we need a custom input component that behaves like a native form control? This is where ControlValueAccessor comes in.

What is ControlValueAccessor ?

ControlValueAccessor is an Angular interface that allows custom form components to integrate with Angular’s form system. It acts as a bridge between the custom component and Angular Forms, ensuring the form can read and update its value correctly.
Without ControlValueAccessor, Angular Forms cannot automatically recognize a custom input component as a valid form control.

Why Use ControlValueAccessor?

By implementing ControlValueAccessor, we can:
✔ Make a custom component behave like a native input field.
✔ Ensure the component updates the form when the user types.
✔ Allow the form to update the component when its value changes externally.
✔ Support Angular’s built-in form validation and status tracking.

Example: Custom Input That Trims Spaces Automatically
Let’s say we need an input field that removes extra spaces whenever a user types.
Step 1: Create the Custom Input Component

import { Component, forwardRef } from '@angular/core';

import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

@Component({

  selector: 'app-trimmed-input',

  template: ``,

  providers: [

    {

      provide: NG_VALUE_ACCESSOR,

      useExisting: forwardRef(() => TrimmedInputComponent),

      multi: true

    }

  ]

})

export class TrimmedInputComponent implements ControlValueAccessor {

  value: string = ''; 

  onChange: (value: string) => void = () => {};

  onTouched: () => void = () => {};

  // When user types, remove spaces and update value

  onInput(event: Event) {

    const inputValue = (event.target as HTMLInputElement).value.trim();

    this.value = inputValue;

    this.onChange(this.value);

  }

  // Update the component when the form control value changes

  writeValue(value: string): void {

    this.value = value ? value.trim() : '';

  }

  // Register function to handle value changes

  registerOnChange(fn: any): void {

    this.onChange = fn;

  }

  // Register function to handle input focus/touch events

  registerOnTouched(fn: any): void {

    this.onTouched = fn;

  }

} 

Step 2: Use the Custom Component in a Form

import { Component } from '@angular/core';

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

@Component({

  selector: 'app-root',

  templateUrl: './app.component.html'

})

export class AppComponent {

  form = new FormGroup({

    username: new FormControl('')

  });

} 

How It Works

  1. The user types text into the field.
  2. Any extra spaces are automatically removed before updating the form control.
  3. The cleaned value is passed to the Angular form control using onChange().
  4. If the form updates externally, writeValue() ensures that the custom component reflects the latest value.

Other Use Cases for ControlValueAccessor

ControlValueAccessor is useful for creating:
• Number-only inputs (e.g., phone numbers, IDs).
• Inputs that automatically format text (e.g., uppercase conversion).
• Custom dropdowns or date pickers that work with Angular Forms.

Key Takeaways

• ControlValueAccessor enables custom components to work with Angular Forms.
• It ensures bidirectional communication between the component and the form control.
• Implementing it properly improves form validation, value tracking, and user experience.

Understanding ControlValueAccessor is crucial for any Angular developer building custom form components. By following the example above, you can create form controls that feel native and integrate seamlessly into your applications.