Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Simplified Validation API #1

Open
mrjackdavis opened this issue Apr 3, 2017 · 0 comments
Open

Simplified Validation API #1

mrjackdavis opened this issue Apr 3, 2017 · 0 comments

Comments

@mrjackdavis
Copy link
Member

mrjackdavis commented Apr 3, 2017

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 invalid

This could be achieved very simply with helper functions. i.e.

const validationOperator = simpleValidation((field,value) => {
  switch(field):
    // ...
})
// ...
LocalStateForm(
  // ...
  validationOperator
)(
  // ...
)
@mrjackdavis mrjackdavis changed the title Improve crazy validation api Simplified Validation API May 2, 2017
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant