Angular has two form strategies. Template-driven forms keep logic in the template — great for simple forms. Reactive forms keep logic in the component class — better for complex validation, dynamic fields, and testing.
Template-Driven Forms
Requires FormsModule in your module. Use ngModel to bind inputs:
// app.module.ts
import { FormsModule } from '@angular/forms';
@NgModule({ imports: [FormsModule, ...] })Ctrl+Enter
HTML
CSS
JS
Preview
export class LoginComponent {
model = { email: '', password: '' }
onSubmit(form: NgForm) {
if (form.valid) console.log(this.model)
}
}Reactive Forms
Requires ReactiveFormsModule. Define the form structure in the component class:
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
export class RegisterComponent implements OnInit {
form!: FormGroup
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.form = this.fb.group({
name: ['', [Validators.required, Validators.minLength(2)]],
email: ['', [Validators.required, Validators.email]],
password: ['', [Validators.required, Validators.minLength(8)]],
})
}
get name() { return this.form.get('name')! }
get email() { return this.form.get('email')! }
get password() { return this.form.get('password')! }
onSubmit() {
if (this.form.valid) console.log(this.form.value)
}
}Ctrl+Enter
HTML
CSS
JS
Preview
Live Form Example
Here's a registration form with real-time validation — the kind Angular would generate:
Ctrl+Enter
HTML
CSS
JS
Preview
Built-in Validators
| Validator | What it checks |
|---|---|
Validators.required | Field is not empty |
Validators.email | Valid email format |
Validators.minLength(n) | At least n characters |
Validators.maxLength(n) | At most n characters |
Validators.pattern(regex) | Matches a regex |
Validators.min(n) | Number ≥ n |
Validators.max(n) | Number ≤ n |
You can also write custom validators — a function that returns null (valid) or an error object.