Skip to content
New issue

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

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

Already on GitHub? Sign in 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant