State-Based Validation
State-based validation allows you to create validation rules that can fail in multiple ways, each with its own specific error message. This is particularly useful for complex validation scenarios where a single property might fail validation for different reasons depending on its state.
Overview
The StateRule class enables you to define validation logic that evaluates to different states, where only one state is considered valid. Each state can have its own custom error message, making it easy to provide specific feedback to users based on why the validation failed.
Basic Usage
State-based validation is implemented using the satisfiesState() method on the validation rules fluent API. Here's how to use it:
import { resolve } from '@aurelia/kernel';
import { IValidationRules } from '@aurelia/validation';
export class RegistrationForm {
private validationRules = resolve(IValidationRules);
public username: string = '';
public constructor() {
this.validationRules
.on(this)
.ensure('username')
.satisfiesState(
'valid',
(value: string) => {
if (!value) return 'empty';
if (value.length < 3) return 'tooShort';
if (!/^[a-zA-Z0-9_]+$/.test(value)) return 'invalidChars';
return 'valid';
},
{
empty: 'Username is required.',
tooShort: 'Username must be at least 3 characters.',
invalidChars: 'Username can only contain letters, numbers, and underscores.'
}
);
}
}How It Works
The satisfiesState() method takes three parameters:
validState: The state value that represents a successful validation (e.g.,
'valid')stateFunction: A function that evaluates the value and returns the current state
messages: An object mapping each possible state to its error message
When validation runs:
The
stateFunctionis called with the current valueIt returns a state (any
PropertyKeytype: string, number, or symbol)If the returned state matches
validState, validation passesIf the returned state is different, validation fails with the corresponding message
Async State Validation
The state function can also be asynchronous, allowing you to perform server-side validation or other async operations:
Access to Object Context
The state function receives both the property value and the object being validated, allowing you to create complex validation logic that depends on other properties:
Complete Example
Here's a comprehensive example showing state-based validation in a user registration form:
Important Notes
Serialization:
StateRuleinstances cannot be serialized to JSON. If you attempt to serialize a state rule, you'll receive a warning in development mode.Message Keys: The state returned by your function becomes the message key. Ensure all possible states have corresponding messages in the messages object.
Valid State: Any state value can be used as the valid state - it doesn't have to be the string
'valid'. You could use numbers, symbols, or any otherPropertyKeyvalue.Dynamic Messages: The messages are evaluated at runtime, so you can include interpolation expressions in them just like standard validation rules.
When to Use State-Based Validation
State-based validation is ideal when:
A single property can fail validation in multiple distinct ways
You want to provide specific, contextual error messages for each failure mode
Your validation logic involves complex conditional checks
You need to perform async validation with multiple possible outcomes
Standard validation rules become unwieldy due to multiple
.when()conditions
For simpler scenarios where a property only needs one type of validation, stick to the standard validation rules like .required(), .matches(), etc.
Last updated
Was this helpful?