gcanti / tcomb-form

Forms library for react
https://gcanti.github.io/tcomb-form
MIT License
1.16k stars 136 forks source link

re-validating not triggering properly #235

Closed benmonro closed 8 years ago

benmonro commented 8 years ago

@gcanti I believe I may have found another issue related to a fix you did here: https://github.com/gcanti/tcomb-form/issues/230

suppose I have the following code:

let latitude = tcb.refinement(tcb.Number, num => num >= -90 && num <= 90, 'latitude');
latitude.getValidationErrorMessage = function(value, path, context) {

    if (!latitude.is(value)) {
        return `${value} is not a valid latitude value`;
    }
}

If i call form.validate() on this, it correctly renders my error message (thanks for that fix). However, if I change the data to something else invalid click save again (which runs validate() again), the first error message is displayed, rather than the 2nd. For example. If i enter a string like "abc" it will show me the error saying that 'abc' is not a valid number. But then if I change the value to 91, instead of saying '91 is not a valid latitude value' it keeps the previous message that abc is not a valid number.

gcanti commented 8 years ago

Hi @benmonro, I can't reproduce this issue.

My test case:

let Latitude = t.refinement(t.Number, num => num >= -90 && num <= 90, 'latitude');
Latitude.getValidationErrorMessage = function(value, path, context) {
    if (!Latitude.is(value)) {
        return `${value} is not a valid latitude value`;
    }
};

const Type = t.struct({
  latitude: Latitude
});

const App = React.createClass({

  onSubmit(evt) {
    evt.preventDefault();
    var value = this.refs.form.getValue();
    if (value) {
      console.log(value);
    }
  },

  render() {
    return (
      <form onSubmit={this.onSubmit}>
        <t.form.Form
          ref="form"
          type={Type}
        />
        <div className="form-group">
          <button type="submit" className="btn btn-primary">Save</button>
        </div>
      </form>
    );
  }

});

My steps:

displays correctly "abc is not a valid latitude value"

displays correctly "91 is not a valid latitude value"

displays correctly "91 is not a valid latitude value"

benmonro commented 8 years ago

oh I forgot to mention that I am overriding the error message for number:

t.Number.getValidationErrorMessage = function(value) { return !value ? " number required": "blah";}

Also i'm using a custom template / skin...

gcanti commented 8 years ago

Once again this is working fine for me:

t.Number.getValidationErrorMessage = function(value) {
  return !value ? 'number required' : 'blah';
};

let Latitude = t.refinement(t.Number, num => num >= -90 && num <= 90, 'latitude');
Latitude.getValidationErrorMessage = function(value, path, context) {
    if (!Latitude.is(value)) {
        return `${value} is not a valid latitude value`;
    }
};

const Type = t.struct({
  latitude: Latitude
});

My steps:

displays correctly "blah"

displays correctly "91 is not a valid latitude value"

displays correctly "91 is not a valid latitude value"

So maybe the problem is in your custom template, but it seems weird.

benmonro commented 8 years ago

hmm, ok. any chance you can post the standalone version of tcomb with each build? I might be able to put it together in a jsbin..

gcanti commented 8 years ago

I found a failing test case containing refinements of structs, working on this...

benmonro commented 8 years ago

Oh good thought I was going crazy On Sat, Oct 24, 2015 at 10:50 AM Giulio Canti notifications@github.com wrote:

I found a failing test case containing refinements of structs, working on this...

— Reply to this email directly or view it on GitHub https://github.com/gcanti/tcomb-form/issues/235#issuecomment-150837052.

gcanti commented 8 years ago

Not sure if it's your same issue though:

const predicate = (x) => x.a > 10 && x.a < 20;

const Type = t.refinement(t.struct({
  a: t.Number
}), predicate);

Type.getValidationErrorMessage = function (x) {
  if (x.a <= 10) {
    return '10';
  }
  if (x.a >= 20) {
    return '20';
  }
};

Your issue seems to regard a refinement of a number instead of a refinement of a struct...

benmonro commented 8 years ago

That is correct. I'm refining a number On Sun, Oct 25, 2015 at 2:05 AM Giulio Canti notifications@github.com wrote:

Not sure if it's your same issue though:

const predicate = (x) => x.a > 10 && x.a < 20; const Type = t.refinement(t.struct({ a: t.Number }), predicate); Type.getValidationErrorMessage = function (x) { if (x.a <= 10) { return '10'; } if (x.a >= 20) { return '20'; } };

  • enter "1" in the a field
  • validate -> displays correctly "10" as error message
  • enter "21"
  • validate -> still displays "10" as error message (not correct)

Your issue seems to regard a refinement of a number instead of a refinement of a struct...

— Reply to this email directly or view it on GitHub https://github.com/gcanti/tcomb-form/issues/235#issuecomment-150903596.

gcanti commented 8 years ago

Ok, just pushed a fix for my failing test case to master, let's see how it goes. Could you please give it a try?

gcanti commented 8 years ago

Fixed in v0.6.10 and v0.7.6