Skip to content
This repository has been archived by the owner on Jul 5, 2019. It is now read-only.

Validation is out of sync with input #14

Open
iurii-kyrylenko opened this issue Dec 13, 2017 · 2 comments
Open

Validation is out of sync with input #14

iurii-kyrylenko opened this issue Dec 13, 2017 · 2 comments
Labels

Comments

@iurii-kyrylenko
Copy link

It seems that validation and input aren't synchronized

See also this gist

Proposed solution setTimeout(() => validate(), 0): perform validation at the next turn of event loop.
It would be nice to solve the out of sync issue inside the neoform package.

@deepsweet deepsweet added the bug label Dec 13, 2017
@deepsweet
Copy link
Contributor

It's hard to know from inside of NeoForm should we postpone validation till the next tick or not, what do you think about something like onChange(e.target.value, validate) as a special case workaround? The value flow is async because input is controlled, i.e. we have an onChange ↔︎ value loop using state.

Another option is to always and explicitly pass values like validate(value) in most cases and validate(e.target.value) in case of onChange.

@iurii-kyrylenko
Copy link
Author

@deepsweet
Thank you for the analysis. You are right, the next tick looks like a hack. In our opinion, the second option (to pass e.target.value in case of onChange) is more preferable. More over, the pending pull request #13 allows easily detect the event type change. Below is a possible implementation of this idea, based on #13:

  1. Module fieldValidation.js. In method validate, along with name, pass an extra property value: event.target.value into form validation handler:
validate(event) {
  if (this.props.validator) {
    const type = event ? event.type : 'unknown';
    const value = (event && event.target) ? event.target.value : null;
    this.context.neoform.validate({ name: this.props.name, value }, type);
  }
}
  1. Module formValidation.js. In method validateField perfom validation, using passed event's value only in case of the change type. Otherwise, validate a value from the state:
validateField({ name, value: eventValue }, type) {
  const validator = this.validators[name];
  const value = (type === 'change') ? eventValue : this.context.neoform.getValue(name);
  validator(value, type)
    .then((message) => {
// ...

This is an example of the input component, with validation of state value on blur and event value on change:

const MyInput = ({
  value='',
  onChange,
  validate,
  validationStatus,
  validationMessage,
  ...props
}) => (
  <span>
    <input
      {...props}
      value={value}
      onBlur={validate}
      onChange={e => {
        onChange(e.target.value)
        if (validationStatus === false) {
          validate(e)
        }
      }}
    />
    {renderError(validationStatus, validationMessage)}
  </span>
)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants