foxhound87 / mobx-react-form

Reactive MobX Form State Management
https://foxhound87.github.io/mobx-react-form
MIT License
1.1k stars 129 forks source link

Show Error Message if Rules are passed without plugins #209

Closed liveresume closed 7 years ago

liveresume commented 7 years ago

Searched previous issues and updated to latest version 1.18.16.

const fields = [
  'jobs',
  'jobs[].jobId',
  'jobs[].companyName',
]
const values = {
  jobs: []
}
const rules = {
  'jobs[].companyName': 'required|string|between:3,75',
}

const form = new MobxReactForm({ fields, values, rules }, { dvr: validatorjs })

When I leave fields blank, or with invalid values, and validate:

await form.$('jobs[0]').validate() == true 

Why aren't the rules applied?

liveresume commented 7 years ago
const name = model.$('companyName')
console.log('validate()', await name.validate())
console.log( 'value', name.value )
console.log( 'rules', name.rules )
console.log( 'isValid', name.isValid )
console.log( 'touched', name.touched )
console.log( 'isDirty', name.isDirty )
console.log( 'isPristine', name.isPristine )

validate() true
value c
rules required|string|between:10,75
isValid true
touched true
isDirty true
isPristine false

Rules look like they are passed down, but validate() result is not correct.

foxhound87 commented 7 years ago

Can you try to use the validate() method with .then() of the normal Promise behavior?

I will replicate your form configuration with the async/await style.

foxhound87 commented 7 years ago

The correct use should be:

  async onInit(form) {
    const isValid = await form.validate();
    console.log('isValid', isValid);
  }
foxhound87 commented 7 years ago

or using an if:


  async onInit(form) {
   if (await form.validate()) {
      console.log('isValid');
    }
  }
foxhound87 commented 7 years ago

Made Tests (PASSES)


// FORM

import validatorjs from 'validatorjs';
import { Form } from '../../../../src';

const fields = [
  'jobs',
  'jobs[].jobId',
  'jobs[].companyName',
];

const values = {
  jobs: [],
};

const rules = {
  'jobs[].companyName': 'required|string|between:3,75',
};

class NewForm extends Form {

  plugins() {
    return {
      dvr: validatorjs,
    };
  }
}

export default new NewForm({ fields, values, rules }, { name: 'Fixes-M' });

// TESTS

  // promise
  describe('Check Fixes-L jobs[0] ', () => {
    it('Check Fixes-L jobs[0]', (done) => {
      $.$M.$('jobs[0]').validate()
        .then((isValid) => {
          expect(isValid).to.be.false; // eslint-disable-line
          done();
        });
    });

  // async/await
  describe('Check Fixes-L jobs[0] ', () => {
    it('Check Fixes-L jobs[0]', (done) => {
      // eslint-disable-next-line
      async () => expect(await $.$M.$('jobs[0]').validate()).to.be.false;
      done();
    });
  });
liveresume commented 7 years ago

using .then() did not work. I noticed checkValidationErrors is set to false on the models. After a little hacking and setting to true, it seemed to start working. What do you think? Why is it set to false?

foxhound87 commented 7 years ago

checkValidationErrors is a mobx computed value.

It is false if there are errors in the field errors stack.

liveresume commented 7 years ago

On a hunch I tried:

class NewForm extends MobxReactForm {
  plugins() {
    return {
      dvr: validatorjs,
    };
  }
}
const form = new NewForm({ fields, values, rules } )

instead of:

const form = new MobxReactForm({ fields, values, rules }, { dvr: validatorjs })

And client side validation now works. Strange.

Looks like there is some kind of breaking change between 2 approaches. Maybe make one a simple wrapper around the other to prevent in future?

liveresume commented 7 years ago

Related to my just posted https://github.com/foxhound87/mobx-react-form/issues/211 I am not getting any errors passed down to components. I know the errors are there due to model.errors()

foxhound87 commented 7 years ago

Hmm, I think you passed the plugins wrong:

this

const form = new MobxReactForm({ fields, values, rules }, { dvr: validatorjs })

to

const form = new MobxReactForm({ fields, values, rules }, { plugins: { dvr: validatorjs } })

The validator wasn't initialized.

liveresume commented 7 years ago

lol, thanks

Maybe we need an error message if rules are passed without plugin?

foxhound87 commented 7 years ago

Yes, absolutely useful, I will implement it.