Skip to content

Instantly share code, notes, and snippets.

@Armenvardanyan95
Created September 5, 2025 08:20
Show Gist options
  • Save Armenvardanyan95/51c790b0b9ded7d6a1f55c363df0492e to your computer and use it in GitHub Desktop.
Save Armenvardanyan95/51c790b0b9ded7d6a1f55c363df0492e to your computer and use it in GitHub Desktop.
function password(path: FieldPath<string>) {
validate(path, (ctx) => {
const value = ctx.value();
if (value && value.length < 8) {
// you can return different errors for different cases using the "kind" field
return customError({
kind: 'tooShort', message: 'Password must be at least 8 characters long',
});
}
if (value && !/[A-Z]/.test(value)) {
return customError({
kind: 'noUpperCase',
message: 'Password must contain at least one uppercase letter'
});
}
return null;
});
}
@Component({
template:
<form>
<label for="email">Email:</label>
<input id="email" type="email" [control]="form.email" />
<label for="password">Password:</label>
<input id="password" type="password" [control]="form.password" />
@if (form.password().invalid()) {
<span class="password-errors">
<!-- iterate over errors and elegantly use "kind" to track -->
@for (error of form.password().errors(); track error.kind) {
{{ error.message }}
}
</span>
}
<button type="submit" [disabled]="form().invalid()">
Login
</button>
</form>,
})
export class LoginPage {
private credentials = signal({
email: '',
password: '',
});
protected readonly form = form(
this.credentials,
credentials => {
required(credentials.email);
email(credentials.email);
required(credentials.password);
password(credentials.password);
}
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment