Forms in Angular - Textnotes

Forms in Angular


Forms are an essential part of most web applications. Angular provides two ways to work with forms: Template-driven forms and Reactive forms. Both allow form validation, error handling, and data binding.

1. Template-driven Forms

Template-driven forms are simple and rely on directives in the template.

1.1 ngModel

Bind form input values to component properties using ngModel.


<form #userForm="ngForm" (ngSubmit)="submitForm(userForm)">
<input name="username" [(ngModel)]="username" placeholder="Username" required>
<button type="submit">Submit</button>
</form>

username = '';

submitForm(form: any) {
console.log(form.value);
}

1.2 Form Validation

Add validation attributes like required, minlength, email.


<input name="email" [(ngModel)]="email" required email>

1.3 Form Errors

Show validation errors in the template:


<div *ngIf="email.invalid && email.touched">
<small *ngIf="email.errors?.required">Email is required</small>
<small *ngIf="email.errors?.email">Invalid email format</small>
</div>

2. Reactive Forms

Reactive forms give more control and are defined entirely in TypeScript.

2.1 FormGroup & FormControl


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

userForm = new FormGroup({
username: new FormControl(''),
email: new FormControl('')
});

<form [formGroup]="userForm" (ngSubmit)="submitReactiveForm()">
<input formControlName="username" placeholder="Username">
<input formControlName="email" placeholder="Email">
<button type="submit">Submit</button>
</form>

2.2 FormBuilder

Simpler way to create reactive forms:


import { FormBuilder, Validators } from '@angular/forms';

constructor(private fb: FormBuilder) { }

userForm = this.fb.group({
username: ['', Validators.required],
email: ['', [Validators.required, Validators.email]]
});

2.3 Custom Validators

Create a function to validate form controls:


import { AbstractControl, ValidationErrors } from '@angular/forms';

function noSpaceValidator(control: AbstractControl): ValidationErrors | null {
if (control.value && control.value.indexOf(' ') >= 0) {
return { noSpace: true };
}
return null;
}

Add to a form control:


username: ['', [Validators.required, noSpaceValidator]]

2.4 Async Validators

Used for server-side validation like checking username availability:


import { AsyncValidatorFn } from '@angular/forms';
import { of } from 'rxjs';
import { delay, map } from 'rxjs/operators';

function asyncValidator(): AsyncValidatorFn {
return (control) => {
return of(control.value).pipe(
delay(1000),
map(value => value === 'admin' ? { forbiddenName: true } : null)
);
};
}

2.5 Reactive Form Validation Messages

Display errors dynamically:


<div *ngIf="userForm.get('username').invalid && userForm.get('username').touched">
<small *ngIf="userForm.get('username').errors?.required">Username is required</small>
<small *ngIf="userForm.get('username').errors?.noSpace">No spaces allowed</small>
</div>

Summary

  1. Angular provides template-driven and reactive forms
  2. Template-driven forms use ngModel and validations in HTML
  3. Reactive forms are defined in TypeScript using FormGroup, FormControl, and FormBuilder
  4. Both support custom validators, async validators, and dynamic error messages
  5. Reactive forms are preferred for complex and large-scale applications