required()
π§ API mapβ
| I want to⦠| Details |
|---|---|
| See every accepted call style | Signatures |
| See common and advanced usage | Usage and behavior |
| Compare presence validators | required versus notNil |
| Customize messages | Message configuration |
| Understand reactive constraints | Reactive behavior |
| Return to the complete catalog | Built-in validators |
π Signaturesβ
required
required(message)
required(options)
This validator has no configurable constraint value. Its options customize the failure message,
which may itself be reactive, and the reactive when condition.
π Usage and behaviorβ
Requires a value to be present. It can be passed directly or called with message options:
const myForm = form({
name: field('', [required]),
surname: field('', [required('Enter your surname.')]),
});
It rejects null, undefined, '', and NaN. It does not reject empty arrays, sets, maps, or objects. Use minLength(1) when a collection must contain an item:
const myForm = form({
roles: field<string[]>([], [required, minLength(1)]),
});
A failure is { kind: 'required', message }. The validator contributes required() === true metadata to its node.
Boolean answers and acceptanceβ
Form Nodes required accepts both true and false. This matches Angular Reactive Forms'
Validators.required for booleans, but differs from Angular Signal Forms' required, which
rejects false.
Use requiredTrue when the value must be exactly true, such as accepting
terms or giving consent. Use required for a yes/no question where either answer is valid.
This comparison is specific to booleans; the validators do not share every empty-value rule. Verified against Angular v22.1.6: Signal Forms emptiness and Reactive Forms validators.
Initialize a yes/no question with field<boolean>(null, [required]): null means unanswered,
and either boolean is valid. These validators do not narrow the field's TypeScript value type
after validation.
import { field, form, notNil, required, requiredTrue } from '../../src/public-api';
const checkout = form({
wantsInvoice: field<boolean>(null, [required]),
acceptedTerms: field(false, [requiredTrue]),
reference: field<string>(null, [notNil]),
});
checkout.wantsInvoice(); // null
checkout.wantsInvoice.valid(); // false: no answer yet
checkout.wantsInvoice.set(false);
checkout.wantsInvoice(); // false
checkout.wantsInvoice.valid(); // true: "No" is an answer
checkout.acceptedTerms.valid(); // false: acceptance must be true
checkout.acceptedTerms.set(true);
checkout.acceptedTerms.valid(); // true
checkout.reference.set('');
checkout.reference(); // ''
checkout.reference.valid(); // true: notNil permits empty strings
checkout.valid(); // true
if (!checkout.valid() || checkout.wantsInvoice() !== false || checkout.reference() !== '') {
throw new Error('A negative answer and an empty reference should pass once the terms are accepted.');
}
checkout.resetToInitial();
if (checkout.valid() || !checkout.wantsInvoice.hasError('required')
|| !checkout.acceptedTerms.hasError('requiredTrue') || !checkout.reference.hasError('notNil')) {
throw new Error('Reset should restore the three distinct validation failures.');
}
checkout.wantsInvoice.required(); // true
checkout.acceptedTerms.required(); // true
checkout.reference.required(); // false: notNil has no HTML required constraint
if (!checkout.wantsInvoice.required() || !checkout.acceptedTerms.required() || checkout.reference.required()) {
throw new Error('Only presence and acceptance rules should contribute required metadata.');
}
A native checkbox receives the HTML required constraint only for requiredTrue, because
HTML requires a required checkbox to be checked. The node's logical required() flag remains
true for both validators. See control binding.
required versus notNilβ
Use required when an empty string or NaN should count as missing. Use
notNil when only null and undefined are forbidden:
| Value | required | notNil |
|---|---|---|
null, undefined | Invalid | Invalid |
'', NaN | Invalid | Valid |
false, true, 0 | Valid | Valid |
| Whitespace-only strings | Valid | Valid |
| Empty arrays, sets, maps, or objects | Valid | Valid |
An active required rule contributes node.required() === true; notNil contributes no
required metadata or native required constraint. This distinction still matters on boolean
fields, even though both rules accept either boolean. Failures use different error kinds and
message-catalog keys: required and notNil.
π¬ Message configurationβ
Every failure has a default English message. Where supported, pass a string as the final argument or use an options object for a static or reactive message, as shown above.
A message function may read signals. Returning undefined continues through node, Angular
provider, process-wide, and built-in message fallbacks. See
Validator messages.
β‘ Reactive behaviorβ
The options object accepts a reactive when predicate. Signals read from its validator context are
tracked; while it returns false, the rule contributes neither errors nor constraint metadata.
const requireCompanyName = signal(false);
const companyName = field('', [
required({ when: () => requireCompanyName() })
]);
Reactive constraint functions and message functions track the signals they read. When a resolved constraint becomes unavailable, validators that support optional constraint sources temporarily stop contributing their error and metadata.
The validator runs synchronously as part of its node's validator source. Disabled, readonly, and hidden nodes skip validation until they become interactive again.