Introduction to Angular Forms
Tags: angular, webdev, programming, javascript
Published: 2021-01-23 00:19:25

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**

Angular is a popular front-end framework made by Google. Like other popular front-end frameworks, it uses a component-based architecture to structure apps.

In this article, we’ll look at the basics of creating forms with Angular.

Different Kinds of Forms
========================

Angular provides 2 different approaches to handling user input through forms.

They are either reactive or template-driven. They both capture events from the view, validate their user input, and create a form model and data model to update, and provide a way to track changes.

Reactive forms are more robust. They’re more scalable, reusable and testable.

Template-driven forms are useful for adding a simple form to an app. They’re easy to add, but they don’t scale as well as reactive forms.

Common Foundation
=================

Both kinds of forms share the following building blocks:

*   `FormControl` — tracks the value and validation status of individual form controls
*   `FormGroup` — tracks the same value and status for a collection of form controls
*   `FormArray` — tracks the same value and status for an array of form control.s.
*   `ControlValueAccessor` — creates a bridge between Angular `FormControl` instances and native DOM elements.

Form Model Setup
================

We can set up the form model of a Reactive form by setting the `formControl` property of an input element.

For example, we can write the following code:

`app.module.ts` :

```
import { BrowserModule } from "@angular/platform-browser";  
import { NgModule } from "@angular/core";  
import { ReactiveFormsModule } from "@angular/forms";  
import { AppComponent } from "./app.component";

@NgModule({  
  declarations: [AppComponent],  
  imports: [BrowserModule, ReactiveFormsModule],  
  providers: [],  
  bootstrap: [AppComponent]  
})  
export class AppModule {}
```

`app.component.ts` :

```
import { Component } from "@angular/core";  
import { FormControl } from "@angular/forms";

@Component({  
  selector: "app-root",  
  templateUrl: "./app.component.html",  
  styleUrls: ["./app.component.css"]  
})  
export class AppComponent {  
  nameControl = new FormControl("");  
}
```

`app.component.html` :

```
<input type="text" [formControl]="nameControl" />
```

In the code above, we added the `ReactiveFormsModule` to our `AppModule` .

Then we created `nameControl` in `AppComponent` .

Finally, we set the `formControl` property to `nameControl` to connect the input to the `FomControl` .

Setup in Template-Driven Forms
==============================

We can use the `ngModel` directive to bind our input value to the a field in our component.

For example, we can write the following:

`app.module.ts` :

```
import { BrowserModule } from "@angular/platform-browser";  
import { NgModule } from "@angular/core";  
import { FormsModule } from "@angular/forms";  
import { AppComponent } from "./app.component";

@NgModule({  
  declarations: [AppComponent],  
  imports: [BrowserModule, FormsModule],  
  providers: [],  
  bootstrap: [AppComponent]  
})  
export class AppModule {}
```

`app.component.ts` :

```
import { Component } from "@angular/core";

@Component({  
  selector: "app-root",  
  templateUrl: "./app.component.html",  
  styleUrls: ["./app.component.css"]  
})  
export class AppComponent {  
  name: string;  
}
```

`app.component.html` :

```
<input type="text" [(ngModel)]="name" />
```

In the code above, we imported the `FormsModule` in `app.module.ts` .

Then we created the `name` field in `AppComponent` to bind the data to the field.

Then we bind our input’s value to `name` via `ngModel` .

Both Reactive and Template-Driven forms provide 2 way binding between the model and the input.

Data Flow in Reactive Forms
===========================

From view to model, the data flow follows the following steps:

1.  User types something into the input
2.  Form input emits an input event
3.  Control value accessor listens for events on the form input and sends the new value to the `FormControl` instance.
4.  The `FormControl` instance emits the new value through the `valueChanges` observable.
5.  Subscribes to `valueChanges` receive the new value

From model to view, the flow is as follows:

1.  The user calls the `nameControl.setValue` method to update the `FormControl` value
2.  The `FormControl` instance emits the new value through the `valueChanges` observable.
3.  Any subscribers to the `valueChanges` observable receive the new value
4.  The control value accessor on the form input element updates the element with the new value

Data Flow in Template-Driven Forms
==================================

The data from the view to the model in template-driven forms are as follows:

1.  User types something into the input element.
2.  The input element emits an input event with the value typed in
3.  The control value accessor attached to the input triggers the `setValue` method on the `FormControl` instance
4.  The `FormControl` instance emits the new value through `valueChanges` observable
5.  Any subscribers to the `valueChanges` observable receives the new value
6.  The control value accessor also calls `NgModel.viewToModelUpdate` method which emits an `ngModelChange` event
7.  `ngModelChanges` triggers model value update

From model to view, the flow is as follows:

1.  The value is updated in the component
2.  Change detection begins
3.  `ngOnChanges` is called on the `NgModel` directive instance because the input value has changed
4.  `ngOnChanges` queues an async task to set the value of the `FormControl` instance
5.  Change detection completes
6.  The task to set `FormControl` instance value is run on next tick
7.  `FormControl` instance emits the latest change through the `valueChanges` observable
8.  Any subscribers to the `valueChanges` observable receives the new value
9.  Control value accessor updates the form input element in the view

Conclusion
==========

We can create Angular forms as Reactive or Template-Driven forms.

Reactive forms are more robust and Template-Driven forms are suitable for simple forms.

They both have the same parts. The control value accessor takes the input value and sets it to the model.