Angular Forms
Tags: angular, forms
Published: 2022-06-29 12:21:49

---
title: Angular Forms
published: true
date: 2022-06-29 02:16:04 UTC
tags: Angular,Forms
canonical_url: https://ricardo-torres.me/index.php/2022/06/28/angular-forms/
---

![](https://ricardo-torres.me/wp-content/uploads/2022/06/form-2.png)

If you started learning Angular from version 1 (AngularJs), maybe you will be more familiarized with configuring a clean Html to handle states and validations in the form. This approach is known as **Template-Driven Forms**.

In contrast Angular count with **Model-Dirven Forms** or **Reactive Forms** which delegates most of the responsability to apply validations and keep states (valid, invalid, touched and dirty) in the form over an object called FormControl located in the TypeScript and not in the HTML like the **Template-Driven Forms**.

## Template Driven Forms

| **Pros** | **Cons** |
| -Very easy to write | Require more lines of HTML code and it can turn it difficult to mantain. |
| -Easy to read and understand | It **can not** be tested, there is no way to apply unit test to their validators. |

## Reactive Forms

This powerful module provides a way to define a form as a **FormGroup** in the TypeScript class to handle states and validations rules that will be associated to each input in the form throught a **formControlName**.

Personally, I think that both are good ways to create Forms in Angular, but your decision over one or another approach is up your needs, the complexity of the forms, if you must create smalls forms with a low complexity you can use Template-Driven Forms, but if you need to create complex forms with Unit test, Reactive Forms will be a smart decision.

Let's create our first Reactive Form.

Open your console and type:

```
ng new reactive-forms
```

```
? Would you like to add Angular routing? (y/N) y
```

![](https://ricardo-torres.me/wp-content/uploads/2022/06/new-project.png)

```
cd reactive-forms
```

```
cd .\src\app
```

Import the module ReactiveFormsModule in the app.module.ts

```
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HeaderComponent } from './layout/header/header.component';
import { FooterComponent } from './layout/footer/footer.component';
import { HttpClientModule } from '@angular/common/http';
import { ReactiveFormsModule } from '@angular/forms';

@NgModule({
  declarations: [AppComponent, HeaderComponent, FooterComponent],
  imports: [BrowserModule, AppRoutingModule, HttpClientModule, ReactiveFormsModule],
  providers: [],
  bootstrap: [AppComponent],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}

```

Create a folder inside app named components and create a component called create-fruits

```
ng g c create-fruits
```

Define the structure of the Form in the class CreateFruitsComponent

```
import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { Record } from 'src/app/model/record';

@Component({
  selector: 'app-create-fruits',
  templateUrl: './create-fruits.component.html',
  styleUrls: ['./create-fruits.component.scss'],
})
export class CreateFruitsComponent implements OnInit {
  title!: string;
  form!: FormGroup;
  fruit!: Record;

  constructor() {}

  ngOnInit(): void {
    this.form = new FormGroup({
      name: new FormControl('', [Validators.required]),
      description: new FormControl('', [Validators.required]),
      image: new FormControl('', [Validators.required]),
      price: new FormControl(0, [Validators.required]),
    });
  }

  onSubmit(): void {
    console.log(this.form);
  }
}
```

As I mentioned before, defining the form in the TypeScript provides a good way to handle the states of our form and all the formControls inside it.

create-fruits.component.html

```
<section class="section">
  <div class="container">
    <h1>New Fruit</h1>
    <div class="form" [formGroup]="form" (ngSubmit)="onSubmit()">
      <div class="form-group">
        <label class="label">Name :</label>
        <input
          type="text"
          id="name"
          formControlName="name"
          placeholder="Name"
          class="input"
        />
        <p
          class="help is-danger walkP"
          *ngIf="
            (form.controls['name'].dirty || form.controls['name'].touched) &&
            form.controls['name'].errors &&
            form.controls['name'].errors['required']
          "
        >
          Name is required!
        </p>
      </div>

      <div class="form-group">
        <label class="label">Description :</label>
        <input
          type="text"
          id="description"
          formControlName="description"
          placeholder="Name"
          class="input"
        />
        <p
          class="help is-danger walkP"
          *ngIf="
            (form.controls['description'].dirty ||
              form.controls['name'].touched) &&
            form.controls['description'].errors &&
            form.controls['description'].errors['required']
          "
        >
          Description is required!
        </p>
      </div>
      <div class="form-group">
        <label class="label">Image :</label>
        <input
          type="text"
          id="image"
          formControlName="image"
          placeholder="Image"
          class="input"
        />
        <p
          class="help is-danger walkP"
          *ngIf="
            (form.controls['image'].dirty || form.controls['name'].touched) &&
            form.controls['image'].errors &&
            form.controls['image'].errors['required']
          "
        >
          Image is required!
        </p>
      </div>
      <div class="form-group">
        <label class="label">Price :</label>
        <input
          type="number"
          id="price"
          formControlName="price"
          placeholder="Price"
          class="input"
        />
        <p
          class="help is-danger walkP"
          *ngIf="
            (form.controls['price'].dirty || form.controls['name'].touched) &&
            form.controls['price'].errors &&
            form.controls['price'].errors['required']
          "
        >
          Image is required!
        </p>
      </div>
      <div class="field is-grouped">
        <div class="control">
          <button
            type="submit"
            class="button is-success"
            (click)="onSubmit()"
            [disabled]="!form.valid"
          >
            Save
          </button>
        </div>
        <div class="control">
          <button class="button is-warning">Cancel</button>
        </div>
      </div>
    </div>
  </div>
</section>

```

Note that I am not using the classic tag form to encapsulate all my html elements, it is not necesary , because I am using a div with a [formGroup]="form" , additionally I am associating each input with its right formControl defined in the TypeScript.

I hope that this post help you in your learning of Angular.

[Live Demo](https://ricardo-torres.net/demos/reactive-forms/#/)  
[Download Code](https://github.com/ricardojavister/angular-demos-reactive-forms)