-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
I propose we improve validation via observables.
- An operator should be passed in to the form HOC
- This operator will receive an observable prop which will receive input when a field is requested for validation. It should also receive enough information to make an informed validation decision. Perhaps the form model will do
- Simultaneously, the form will receive an update which says the field is undergoing validation
- The operator's returned observable should receive input each time a field is validated. It should not be necessary to return 1:1 validation results for validation requests. There could be many validation results for a single input
At it's core:
|-o---------o------------o------>|
ValidationOperator
|-o------------o---------o---o-->|
Where the first observable input is of type
{
field:string, // pointer to field
model:ImmutableJS.Map
}And returned observable should output
{
field:string, // pointer to field
status:'VALID' | 'INVALID',
message?:string // Required when INVALID
}Used like so:
const validationOperator = source=>{
// ...
}
// ...
LocalStateForm(
// ...
validationOperator
)(
// ...
)Examples
Very simple
(source)=>
source
.map(validate=>{
const { field, model } = validate;
const fieldValue = model.get(field)
if(validate.field === 'name'){
return {
field,
status: fieldValue == true ? 'VALID' : 'INVALID',
message:'Name is required'
};
} else if(validate.field === 'email'){
return {
field,
status: fieldValue.includes('@') ? 'VALID' : 'INVALID',
message:'Email must contain "@"'
};
}
})ASync validation
Assuming there's a single field username
(source)=>
source
.switchMap(async (validate)=>{
const { field, model } = validate;
const fieldValue = model.get(field)
const usernameAvailable = await IsUsernameAvailable(fieldValue);
return {
field,
status: usernameAvailable ? 'VALID' : 'INVALID',
message:`Username "${fieldValue}" is invalid`
}
})But its complicated
Such a powerful API is difficult to grok.
90% of the time, developers will just want to use a simple function.
(field, value)=>void // Throws error if invalidThis could be achieved very simply with helper functions. i.e.
const validationOperator = simpleValidation((field,value) => {
switch(field):
// ...
})
// ...
LocalStateForm(
// ...
validationOperator
)(
// ...
)Metadata
Metadata
Assignees
Labels
No labels