3.3 KiB
3.3 KiB
type, title, description, tags, timestamp
| type | title | description | tags | timestamp | ||||
|---|---|---|---|---|---|---|---|---|
| guide | Setup Form Field Errors | Pure error-computation functions that drive the inline validation messages on the first-admin modal. |
|
2026-07-21T16:48:20Z |
Purpose
The three pure helpers exported by
frontend/src/app/features/setup/setup-create-admin.field-errors.ts
turn the raw Angular reactive-form control state into the user-facing
strings shown beside each input on the first-admin modal. Keeping them
as standalone functions (instead of computed() signals inside the
component) makes them trivially unit-testable in isolation — see
tests/frontend/setup-create-admin.spec.ts.
Helpers
| Function | Returns | Reads |
|---|---|---|
usernameError |
string | null |
value, touched, plus errors keys required/minlength/maxlength/pattern. |
passwordError |
string | null |
value, touched, plus errors.required. |
confirmError |
string | null |
value, touched, errors.required, and the group-level groupMismatch flag from the password-match validator. |
All three return null when the field is not yet touched (or, for
confirmError, when no group-level mismatch has been raised), so the
UI stays clean until the user has interacted with the form.
Inputs
export interface FieldErrorContext {
value: string;
touched: boolean;
errors: Partial<Record<FieldErrorKey, true>> | null;
groupMismatch?: boolean;
}
export type FieldErrorKey =
| 'required'
| 'minlength'
| 'maxlength'
| 'pattern'
| 'passwordMismatch';
Examples
usernameError({
value: 'ab',
touched: true,
errors: { minlength: true },
});
// -> 'Username must be at least 3 characters'
confirmError({
value: 'hunter2',
touched: true,
errors: null,
groupMismatch: true,
});
// -> 'Passwords do not match'
passwordError({
value: '',
touched: true,
errors: { required: true },
});
// -> 'Password is required'
Wiring
SetupCreateAdminComponent(frontend/src/app/features/setup/setup-create-admin.component.ts) binds the three helpers to template method calls (usernameError(),passwordError(),confirmError()) that read the correspondingFormControland pass its current state.- The template
(
frontend/src/app/features/setup/setup-create-admin.component.html) renders the returned string inside a<small class="field-error">withdata-testid="setup-{username|password|confirm}-error", and mirrors the result on the input via[attr.aria-invalid]. tests/frontend/setup-create-admin.spec.tsexercises every code path of the three helpers directly — no Angular TestBed is required.
See also
- First-Run Bootstrap — how the helpers surface to the operator.
- Setup Endpoint — server-side validation that mirrors these messages.
- Key Files Index