Both Template-driven and Reactive forms in Angular support validations, but the way validations are implemented and managed differs between the two approaches. Below are examples of both, showcasing form validations:
- Template-driven forms with Validations In template-driven forms, validation is typically done directly in the template using Angular directives such as required, minlength, email, and others. You can also access form validity through the ngForm directive. Example of Template-Driven Form with Validations:
<!-- app.component.html -->
<form #userForm="ngForm" (ngSubmit)="onSubmit(userForm)">
<div>
<label for="name">Name</label>
<input
type="text"
id="name"
name="name"
ngModel
required
minlength="3"
#name="ngModel"
/>
<div *ngIf="name.invalid && name.touched">
<small *ngIf="name.errors?.required">Name is required.</small>
<small *ngIf="name.errors?.minlength">Name must be at least 3 characters long.</small>
</div>
</div>
<div>
<label for="email">Email</label>
<input
type="email"
id="email"
name="email"
ngModel
required
email
#email="ngModel"
/>
<div *ngIf="email.invalid && email.touched">
<small *ngIf="email.errors?.required">Email is required.</small>
<small *ngIf="email.errors?.email">Please enter a valid email address.</small>
</div>
</div>
<button type="submit" [disabled]="!userForm.valid">Submit</button>
</form>
// app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
})
export class AppComponent {
onSubmit(form: any) {
if (form.valid) {
console.log('Form Submitted', form.value);
} else {
console.log('Form is invalid');
}
}
}
Validation Breakdown:
Required Validation: Ensures that the input field is not empty.
Minlength Validation: Ensures that the name field has at least 3 characters.
Email Validation: Ensures that the email is in a valid format.
Touched State: Displays validation error messages only after the user has interacted with the field (touched).
Pros of Template-Driven Validations:
Declarative and Simple: You define validations directly in the template, making it quick and easy to set up.
Automatic Binding: Angular takes care of binding form controls to the template, reducing boilerplate code in the component class.
Cons:
Limited Flexibility: Template-driven forms are best for simple forms. Complex logic or dynamic form behavior may require more effort.
Harder to Manage Dynamic Validations: Handling dynamic or conditional validations can be challenging in template-driven forms.
2. Reactive Forms with Validations
Reactive forms are more programmatic, and you define form controls, groups, and validations in the component class. This approach provides greater flexibility and control.
Example of Reactive Form with Validations:
<!-- app.component.html -->
<form [formGroup]="userForm" (ngSubmit)="onSubmit()">
<div>
<label for="name">Name</label>
<input
type="text"
id="name"
formControlName="name"
/>
<div *ngIf="userForm.get('name')?.invalid && userForm.get('name')?.touched">
<small *ngIf="userForm.get('name')?.hasError('required')">Name is required.</small>
<small *ngIf="userForm.get('name')?.hasError('minlength')">Name must be at least 3 characters long.</small>
</div>
</div>
<div>
<label for="email">Email</label>
<input
type="email"
id="email"
formControlName="email"
/>
<div *ngIf="userForm.get('email')?.invalid && userForm.get('email')?.touched">
<small *ngIf="userForm.get('email')?.hasError('required')">Email is required.</small>
<small *ngIf="userForm.get('email')?.hasError('email')">Please enter a valid email address.</small>
</div>
</div>
<button type="submit" [disabled]="userForm.invalid">Submit</button>
</form>
// app.component.ts
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
})
export class AppComponent {
userForm: FormGroup;
constructor(private fb: FormBuilder) {
this.userForm = this.fb.group({
name: ['', [Validators.required, Validators.minLength(3)]],
email: ['', [Validators.required, Validators.email]],
});
}
onSubmit() {
if (this.userForm.valid) {
console.log('Form Submitted', this.userForm.value);
} else {
console.log('Form is invalid');
}
}
}
Validation Breakdown:
Required Validation: Ensures the name and email fields are not empty.
Minlength Validation: Ensures that the name field has at least 3 characters.
Email Validation: Ensures that the email field contains a valid email format.
Touched State: Error messages are shown only if the form control is touched (i.e., the user interacts with the input).
Pros of Reactive Forms Validations:
Greater Control: You have full control over form data, validation logic, and form state.
Scalability: Works well for large and complex forms. It’s easier to manage dynamic forms or conditional validations.
Better for Unit Testing: Reactive forms are easier to unit test because the logic is defined in the component.
Cons:
More Boilerplate Code: You have to define the form group and validation logic in the component, which can make the setup more verbose.
Less Declarative: Unlike template-driven forms, you need to define much of the form behavior in the TypeScript class.
When to Use Each:
- Template-Driven Forms: Best suited for simple forms with basic validation logic. It’s great when you want a quick, declarative setup.
- Reactive Forms: Ideal for more complex forms, dynamic forms, or when you need full control over form behavior, validation, and state management.
Both approaches support validations, and the choice between them depends on the complexity of your form and how much control you need over the form behavior.
Top comments (0)