Reactive Forms provide a model-driven approach to handling form inputs — the form structure is defined in the component class, making it easier to test, validate, and manipulate dynamically.
import { Component, inject } from '@angular/core';
import { ReactiveFormsModule, FormBuilder, Validators } from '@angular/forms';
@Component({
selector: 'app-register',
standalone: true,
imports: [ReactiveFormsModule],
templateUrl: './register.component.html',
})
export class RegisterComponent {
private fb = inject(FormBuilder);
form = this.fb.group({
name: ['', [Validators.required, Validators.minLength(2)]],
email: ['', [Validators.required, Validators.email]],
password: ['', [Validators.required, Validators.minLength(8)]],
role: ['user', Validators.required],
agree: [false, Validators.requiredTrue],
});
get name() { return this.form.get('name')! }
get email() { return this.form.get('email')! }
get password() { return this.form.get('password')! }
onSubmit(): void {
if (this.form.invalid) { this.form.markAllAsTouched(); return; }
console.log(this.form.value);
}
}
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<input formControlName="name" placeholder="Full name" />
@if (name.invalid && name.touched) {
<span class="error">
@if (name.errors?.['required']) { Name is required. }
@if (name.errors?.['minlength']) { At least 2 characters. }
</span>
}
<input formControlName="email" type="email" />
@if (email.invalid && email.touched) {
<span class="error">Valid email required.</span>
}
<button type="submit" [disabled]="form.invalid">Register</button>
</form>