Angular is a powerful and widely used web development framework that allows developers to create modern, interactive, and robust applications. One of the critical aspects of building a web application is handling forms. In this tutorial, we will explore how to handle forms in Angular with TypeScript.


Prerequisites

Before we start, you should have some knowledge of the following:

  • HTML
  • TypeScript
  • Angular


Creating a Form

To create a form in Angular, we use the FormGroup and FormControl classes provided by the @angular/forms module. These classes help us manage the form's state and provide built-in validation features.

Let's create a simple form that allows the user to enter their name, email, and message:

<form [formGroup]="contactForm" (ngSubmit)="onSubmit()">
  <label>
    Name:
    <input type="text" formControlName="name" required />
  </label>

  <label>
    Email:
    <input type="email" formControlName="email" required />
  </label>

  <label>
    Message:
    <textarea formControlName="message" required></textarea>
  </label>

  <button type="submit">Send</button>
</form>

In the code above, we create a form element with three label elements that contain an input and a textarea element. Each input element has a formControlName attribute that we will use later to bind the form controls to the form group.

We also set the formGroup attribute to the contactForm property, which we will define in the TypeScript code. Finally, we attach the ngSubmit event to the onSubmit() method, which we will implement later.


Creating the Form Group

Now, let's create the contactForm property in our component's TypeScript code:

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

@Component({
  selector: 'app-contact',
  templateUrl: './contact.component.html',
  styleUrls: ['./contact.component.css'],
})
export class ContactComponent {
  contactForm = new FormGroup({
    name: new FormControl('', [Validators.required]),
    email: new FormControl('', [Validators.required, Validators.email]),
    message: new FormControl('', [Validators.required]),
  });
}


In the code above, we import the necessary classes from the @angular/forms module. We then define the contactForm property as a new instance of the FormGroup class. Inside the FormGroup constructor, we create three FormControl instances that represent the name, email, and message form controls.

Each FormControl is initialized with an empty string as its initial value and an array of Validators. We use the Validators.required validator to make sure the user enters a value in all fields and the Validators.email validator to validate the email field's format.


Handling Form Submission

To handle form submission, we need to implement the onSubmit() method. This method is called when the user clicks the Submit button. Let's implement the method in our component's TypeScript code:

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

@Component({
  selector: 'app-contact',
  templateUrl: './contact.component.html',
  styleUrls: ['./contact.component.css'],
})
export class ContactComponent {
  contactForm = new FormGroup({
    name: new FormControl('', [Validators.required]),
    email: new FormControl('', [Validators.required, Validators.email]),
    message: new FormControl('', [Validators.required]),
  });

  onSubmit() {
    if (this.contactForm.valid) {
// Implement form submission logic here
console.log(this.contactForm.value);
} else {
// Mark form controls as touched to trigger validation errors
Object.values(this.contactForm.controls).forEach(control => control.markAsTouched());
}
}
}

In the code above, we first check if the form is valid by calling the `valid` property of the `contactForm` instance. If the form is valid, we can implement our form submission logic. In this case, we simply log the form values to the console.

If the form is not valid, we use the `markAsTouched()` method to mark all form controls as touched. This will trigger validation errors and display them to the user.


Displaying Validation Errors

Now that we have implemented form validation, we need to display validation errors to the user. Let's update our HTML code to display validation errors:

<form [formGroup]="contactForm" (ngSubmit)="onSubmit()">
  <label>
    Name:
    <input type="text" formControlName="name" required />
    <div *ngIf="contactForm.get('name').invalid && (contactForm.get('name').dirty || contactForm.get('name').touched)">
      <div *ngIf="contactForm.get('name').errors.required">Name is required.</div>
    </div>
  </label>

  <label>
    Email:
    <input type="email" formControlName="email" required />
    <div *ngIf="contactForm.get('email').invalid && (contactForm.get('email').dirty || contactForm.get('email').touched)">
      <div *ngIf="contactForm.get('email').errors.required">Email is required.</div>
      <div *ngIf="contactForm.get('email').errors.email">Invalid email format.</div>
    </div>
  </label>

  <label>
    Message:
    <textarea formControlName="message" required></textarea>
    <div *ngIf="contactForm.get('message').invalid && (contactForm.get('message').dirty || contactForm.get('message').touched)">
      <div *ngIf="contactForm.get('message').errors.required">Message is required.</div>
    </div>
  </label>

  <button type="submit">Send</button>
</form>

In the code above, we use the *ngIf directive to conditionally render validation error messages. We first check if the form control is invalid and has been either dirty or touched. If so, we display the corresponding error message.

For example, in the Name input, we check if the name form control is invalid and either dirty or touched. If so, we display the error message "Name is required."


Conclusion

In this tutorial, we have explored how to handle forms in Angular with TypeScript. We have learned how to create a form, define form validation, handle form submission, and display validation errors. With this knowledge, you can now create powerful and interactive forms in your Angular applications.