Angular Reactive forms are an essential part of building modern web applications. These forms allow for a more streamlined approach to managing data input and validation, and they are highly customizable. In this blog post, we will explore how to create an Angular Reactive form with display validation.

Prerequisites
You should have a basic understanding of Angular and Reactive Forms. If you're unfamiliar with these topics, you can check out the official Angular documentation at the portal.

The source code can be downloaded from GitHub

I have used the below tools to prepare this tutorial.
    Angular CLI - 15.1.6
    Node: 18.14.0
    NPM – 9.3.1
    Visual Studio Code

To get started, let's assume we have a simple form that collects basic user information like name, email, and phone number. We'll create a FormGroup in our component to hold our form controls and validators:
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators, FormControl, AbstractControl } from '@angular/forms';

@Component({
    selector: 'app-user-form',
    templateUrl: './userform.component.html',
    styleUrls: ['./userform.component.scss']
})
export class UserformComponent implements OnInit {
    userform: FormGroup = new FormGroup({
        name: new FormControl(''),
        email: new FormControl(''),
        phone: new FormControl('')
    });
    submitted = false;
    constructor(private fb: FormBuilder) {}
    ngOnInit(): void {
        this.userform = this.fb.group({
            name: ['', Validators.required],
            email: ['', [Validators.required, Validators.email]],
            phone: ['', [Validators.required, Validators.minLength(10)]]
        });
    }
    get f(): {
        [key: string]: AbstractControl
    } {
        return this.userform.controls;
    }
    onSubmit(): void {
        this.submitted = true;
        if (this.userform.invalid) {
            return;
        }
        console.log(JSON.stringify(this.userform.value, null, 2));
    }
}

We're using the FormBuilder service to create our form controls and validators. The name control is required, the email control is required and must be a valid email address, and the phone control is required and must be at least 10 digits long.

Now that we have our form set up, we can use it in our template:
<div class="register-form">
<form  (ngSubmit)="onSubmit()" [formGroup]="userform">
    <div class="form-group">
      <label>Name:</label>
      <input type="text" formControlName="name"
      class="form-control"
      [ngClass]="{ 'is-invalid': submitted && f['name'].errors }"
      >
      <div *ngIf="submitted && f['name'].errors" class="invalid-feedback">
        <div *ngIf="f['name'].errors['required']">
          Name is required
        </div>
      </div>
    </div>

    <div class="form-group">
      <label>Email:</label>
      <input type="email" formControlName="email"
      class="form-control"
      [ngClass]="{ 'is-invalid': submitted && f['email'].errors }"
      >
      <div *ngIf="submitted && f['email'].errors" class="invalid-feedback">
        <div *ngIf="f['email'].errors['required']">
          Email is required
        </div>
        <div *ngIf="f['email'].errors['email']">
          Email is not valid
        </div>
      </div>
    </div>

    <div class="form-group">
      <label>Phone:</label>
      <input type="tel" formControlName="phone"
      class="form-control"
      [ngClass]="{ 'is-invalid': submitted && f['phone'].errors }"
      minlength="10" maxlength="11">
      <div *ngIf="submitted && f['phone'].errors" class="invalid-feedback">
        <div *ngIf="f['phone'].errors['required']">
              Phone is required
        </div>
            <div *ngIf="f['phone'].errors['minlength']">
              Phone must be at least 10 digits
            </div>
        </div>
    </div>
    <div class="form-group">
    <button type="submit" class="btn btn-primary">Submit</button>
  </div>
  </form>
</div>

In our template, we bind our formGroup to the userForm property in our component. We're also using the formControlName directive to bind each input field to its respective control.

We display validation messages for each control using Angular's *ngIf directive. We're checking if the control is invalid and either dirty or touched. If it is, we're displaying the relevant error message. For example, if the name control is required and the user has not entered anything, we'll display the "Name is required" error message.

We're also disabling the submit button if the form is invalid, which means validation errors are present.

Now that we have our form set up and displaying validation messages, we must handle form submission in our component. We'll create an onSubmit() method that will log the form data to the console:
onSubmit(): void {
    this.submitted = true;
    if (this.userform.invalid) {
        return;
    }
    console.log(JSON.stringify(this.userform.value, null, 2));
}

The sample screenshot is given below.


And that's it! We've created an Angular Reactive form with display validation with just a few lines of code. This form is highly customizable and can be expanded to collect more complex data easily.

With the assistance of ChatGPT, I am thrilled to have completed my third blog post.