Form Controls

in Angular


Adithya Sreyaj

Front-end @ Hypersonix

Angular & Forms




Angular has in-built tools to work with forms. Being a framework, this is a really good advantage Angular has over others.


The Angular Forms APIs captures user input events from the view, validate the user input, create a form model and data model to update, and provide a way to track changes.

  • Template Driven Forms
  • Reactive Forms

Both of them work with the same Forms API.

Angular Forms API



Template Driven Forms

  • Easiest way to get started with forms in Angular
  • Low entry barrier
  • Directives are used to interact with HTML elements
  • Logic can be solely managed in the template
  • Can be used for simple and complex forms
import { Component } from "@angular/core";

  selector: "app-root",
      <label for="email">Email</label>
      <input type="email" id="email" [(ngModel)]="email" />
  styleUrls: ["./app.component.css"]
export class AppComponent {
  email = "";





Reactive Forms

  • Needs getting used to
  • Direct access to the form data model
  • Robust, scalable, reusable, & testable
  • Easier if you already follow reactive approach
  • For form-heavy apps, Ideal choice.
import { Component } from "@angular/core";
import { FormControl } from "@angular/forms";

  selector: "app-root",
  template: `
      <label for="email">Email</label>
      <input type="email" id="email" [formControl]="email" />
  styleUrls: ["./app.component.css"]
export class AppComponent {
  email = new FormControl("");

How does angular connect to html form elements?




HTML form elements like input, radio, checkbox etc has certain properties and events that can be used to interact with them.

// Listent to the user input
input.addEventListener("input", (evt) => {

// Update the value of the input field
button.addEventListener("click", () => {
  input.setAttribute("value", "Adithya");

// Disable the input field
disable.addEventListener("click", () => {
  input.setAttribute("disabled", true);
  • Creates a wrapper around these native APIs and events.
  • This abstracts away most of the logic needed for interaction.
  • Angular then exposes a simple class called Control Value Accessor to interact with the elements in a nicer way.





Angular has created Control Value Accessors

for all the basic input elements that we have:

Find all Control Value Accessors in the docs

  host: {
    '(change)': 'onChange($',
    '(blur)': 'onTouched()'
export class CheckboxControlValueAccessor 
  extends BuiltInControlValueAccessor 
  implements ControlValueAccessor {
  writeValue(value: any): void {
    this.setProperty('checked', value);

Custom Form Controls




Similar to what Angular has done with build-in value accessors, we can create our own accessors by implementing the ControlValueAccessor interface.

interface ControlValueAccessor {
  writeValue(obj: any): void
  registerOnChange(fn: any): void
  registerOnTouched(fn: any): void
  setDisabledState(isDisabled: boolean)?: void

Let's dive deep into each of these properties!

COntrolValueAccessor interface




  • This function will be called by the Forms API to update the view.
  • The new value to write will be passed as the function parameter.
  • It doesn't return anything.

writeValue(obj: any): void;

  • Registers a callback function that is called when the control's value changes in the UI.
  • So when we are building custom form elements, when a user makes changes from the UI, we call our registered function to update the form data model.
  • This is how we let Angular know that we need to update the model.

registerOnChange(fn: any): void;






  • Registers a callback function that is called by the forms API on initialisation to update the form model on blur.
  • When user interacts with out custom element, we can mark it as touched.

registerOnTouched(fn: any): void

  • Function that is called by the forms API when the control status changes to or from 'DISABLED'.
  • We can write the custom logic which will disable our custom element.

setDisabledState(isDisabled: boolean)?: void 






Now let's see how its done!

  • Custom Country Selector Element
  • Custom Credit Card Input Element
  • We'll use combination of Reactive Forms & Template Driven Forms




Here are some important links:

Feel free to reach out to me on twitter @AdiSreyaj


Made with