Skip to main content

Lab 17: Signal Forms

πŸ“– Resources​

πŸš€ Starter Code​

step-17-album-wholesale-v21-post-signal-resource

In this lab, you'll adopt Angular's new signal-based forms API. You'll create forms using the form() function, bind inputs with the [field] directive, implement validators declaratively, and access form state through signals.

πŸ“ Instructions​

Step 1: Create Signal Form​

Import and create a signal-based form:

import { form, Field, required, min } from '@angular/forms/signals';

albumForm = form(
signal<Album>({
name: '',
artist: '',
price: 0
}),
(path) => {
required(path.name);
required(path.artist);
min(path.price, 0);
}
);

Step 2: Use Field Directive​

Bind form fields with the [field] directive:

<input matInput [field]="albumForm.name">

Step 3: Display Validation Errors​

Show errors from the form field:

@for (error of albumForm.name().errors(); track error.kind) {
@if (error.kind === 'required') {
<mat-error>Name is required</mat-error>
}
}

Step 4: Custom Validator​

Add a custom validator function:

function priceEndsWithNine(value: number) {
const lastDigit = value.toString().slice(-1);
return lastDigit !== '9' ? { kind: 'priceEndingWith9', message: 'Price must end with 9' } : null;
}

// Apply it
albumForm = form(signal<Album>({ ... }), (path) => {
validate(path.price, (ctx) => priceEndsWithNine(ctx.value()));
});