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

onSubmit being called before validation #156

Closed
duro opened this issue Oct 21, 2015 · 12 comments
Closed

onSubmit being called before validation #156

duro opened this issue Oct 21, 2015 · 12 comments

Comments

@duro
Copy link

duro commented Oct 21, 2015

Here is a simple form component I have setup.

Here is the main page container:

import React, {Component} from 'react';
import LoginForm from './LoginForm';

export default class Login extends Component {

  handleSubmit() {
    console.log('submit');
  }

  render() {
    return (
      <div>
        <h1>Login</h1>
        <LoginForm onSubmit={this.handleSubmit.bind(this)} />
      </div>
    );
  }
}

And here is the LoginForm.js container/component:

import React, {Component, PropTypes} from 'react';
import {connectReduxForm} from 'redux-form';

function validateLogin(data, props) {
  const errors = {};
  if(!data.email || data.email.length > 0) {
    errors.name = 'Required';
  }
  return errors;
}

@connectReduxForm({
  form: 'login',
  fields: ['email', 'password'],
  validate: validateLogin
})
export default class LoginForm extends Component {

  static propTypes = {
    fields: PropTypes.object.isRequired,
    handleSubmit: PropTypes.func.isRequired,
    onSubmit: PropTypes.func.isRequired
  }

  render() {

    const { fields: {email, password}, handleSubmit } = this.props;

    return (
      <form>
        <div>
          <label>Email Address</label>
          <input type='text' {...email} />
          {name.error && name.touched && <div>{name.error}</div>}
        </div>

        <div>
          <label>Password</label>
          <input type='password' {...password} />
          {password.error && password.touched && <div>{password.error}</div>}
        </div>

        <div><button onClick={handleSubmit(this.props.onSubmit)}>Submit</button></div>
      </form>
    );
  }
}

The problem I am running into is that the handleSubmit in the parent container is getting called before the validateLogin function is called and validations have either happened successfuly, or not.

My expection is that the validator function would get called, and if there were no errors, then the handleSubmit that I passed in from the onSubmit prop would get called.

Am I doing something wrong, have the wrong expectation, or is this a bug?

@wmertens
Copy link
Contributor

First of all, questions should go on stackoverflow, reactiflux etc. (at
least that's the case with most projects and I think this one too)

Secondly, don't pass onSubmit to handleSubmit, it already takes care of
that. I think that's why it's behaving this way…

On Wed, Oct 21, 2015, 2:13 AM Adam Duro notifications@github.com wrote:

Here is a simple form component I have setup.

Here is the main page container:

import React, {Component} from 'react';
import LoginForm from './LoginForm';

export default class Login extends Component {

handleSubmit() {
console.log('submit');
}

render() {
return (


Login




);
}
}

And here is the LoginForm.js container/component:

import React, {Component, PropTypes} from 'react';
import {connectReduxForm} from 'redux-form';

function validateLogin(data, props) {
const errors = {};
if(!data.email || data.email.length > 0) {
errors.name = 'Required';
}
return errors;
}

@connectReduxForm({
form: 'login',
fields: ['email', 'password'],
validate: validateLogin
})
export default class LoginForm extends Component {

static propTypes = {
fields: PropTypes.object.isRequired,
handleSubmit: PropTypes.func.isRequired,
onSubmit: PropTypes.func.isRequired
}

render() {

const { fields: {email, password}, handleSubmit } = this.props;

return (
  <form>
    <div>
      <label>Email Address</label>
      <input type='text' {...email} />
      {name.error && name.touched && <div>{name.error}</div>}
    </div>

    <div>
      <label>Password</label>
      <input type='password' {...password} />
      {password.error && password.touched && <div>{password.error}</div>}
    </div>

    <div><button onClick={handleSubmit(this.props.onSubmit)}>Submit</button></div>
  </form>
);

}
}

The problem I am running into is that the handleSubmit in the parent
container is getting called before the validateLogin function is called
and validations have either happened successfuly, or not.

My expection is that the validator function would get called, and if there
were no errors, then the handleSubmit that I passed in from the onSubmit
prop would get called.

Am I doing something wrong, have the wrong expectation, or is this a bug?


Reply to this email directly or view it on GitHub
#156.

Wout.
(typed on mobile, excuse terseness)

@duro
Copy link
Author

duro commented Oct 21, 2015

I already tried not passing onSubmit explicitly. Same issue.

So far this is appearing bug like, hence submitting an issue.

On Tuesday, October 20, 2015, Wout Mertens notifications@github.com wrote:

First of all, questions should go on stackoverflow, reactiflux etc. (at
least that's the case with most projects and I think this one too)

Secondly, don't pass onSubmit to handleSubmit, it already takes care of
that. I think that's why it's behaving this way…

On Wed, Oct 21, 2015, 2:13 AM Adam Duro <notifications@github.com
javascript:_e(%7B%7D,'cvml','notifications@github.com');> wrote:

Here is a simple form component I have setup.

Here is the main page container:

import React, {Component} from 'react';
import LoginForm from './LoginForm';

export default class Login extends Component {

handleSubmit() {
console.log('submit');
}

render() {
return (

Login

);
}
}

And here is the LoginForm.js container/component:

import React, {Component, PropTypes} from 'react';
import {connectReduxForm} from 'redux-form';

function validateLogin(data, props) {
const errors = {};
if(!data.email || data.email.length > 0) {
errors.name = 'Required';
}
return errors;
}

@connectReduxForm({
form: 'login',
fields: ['email', 'password'],
validate: validateLogin
})
export default class LoginForm extends Component {

static propTypes = {
fields: PropTypes.object.isRequired,
handleSubmit: PropTypes.func.isRequired,
onSubmit: PropTypes.func.isRequired
}

render() {

const { fields: {email, password}, handleSubmit } = this.props;

return (

Email Address {name.error && name.touched &&
{name.error}
}
Password {password.error && password.touched &&
{password.error}
}
Submit

);
}
}

The problem I am running into is that the handleSubmit in the parent
container is getting called before the validateLogin function is called
and validations have either happened successfuly, or not.

My expection is that the validator function would get called, and if
there
were no errors, then the handleSubmit that I passed in from the onSubmit
prop would get called.

Am I doing something wrong, have the wrong expectation, or is this a bug?


Reply to this email directly or view it on GitHub
#156.

Wout.
(typed on mobile, excuse terseness)


Reply to this email directly or view it on GitHub
#156 (comment).

@wmertens
Copy link
Contributor

Then you should have said so from the start, saving all of us time :-)

Are you sure the validate is not running, I don't see a console log?

On Wed, Oct 21, 2015, 7:31 AM Adam Duro notifications@github.com wrote:

I already tried not passing onSubmit explicitly. Same issue.

So far this is appearing bug like, hence submitting an issue.

On Tuesday, October 20, 2015, Wout Mertens notifications@github.com
wrote:

First of all, questions should go on stackoverflow, reactiflux etc. (at
least that's the case with most projects and I think this one too)

Secondly, don't pass onSubmit to handleSubmit, it already takes care of
that. I think that's why it's behaving this way…

On Wed, Oct 21, 2015, 2:13 AM Adam Duro <notifications@github.com
javascript:_e(%7B%7D,'cvml','notifications@github.com');> wrote:

Here is a simple form component I have setup.

Here is the main page container:

import React, {Component} from 'react';
import LoginForm from './LoginForm';

export default class Login extends Component {

handleSubmit() {
console.log('submit');
}

render() {
return (

Login

);
}
}

And here is the LoginForm.js container/component:

import React, {Component, PropTypes} from 'react';
import {connectReduxForm} from 'redux-form';

function validateLogin(data, props) {
const errors = {};
if(!data.email || data.email.length > 0) {
errors.name = 'Required';
}
return errors;
}

@connectReduxForm({
form: 'login',
fields: ['email', 'password'],
validate: validateLogin
})
export default class LoginForm extends Component {

static propTypes = {
fields: PropTypes.object.isRequired,
handleSubmit: PropTypes.func.isRequired,
onSubmit: PropTypes.func.isRequired
}

render() {

const { fields: {email, password}, handleSubmit } = this.props;

return (

Email Address {name.error && name.touched &&
{name.error}
}
Password {password.error && password.touched &&
{password.error}
}
Submit

);
}
}

The problem I am running into is that the handleSubmit in the parent
container is getting called before the validateLogin function is called
and validations have either happened successfuly, or not.

My expection is that the validator function would get called, and if
there
were no errors, then the handleSubmit that I passed in from the
onSubmit
prop would get called.

Am I doing something wrong, have the wrong expectation, or is this a
bug?


Reply to this email directly or view it on GitHub
#156.

Wout.
(typed on mobile, excuse terseness)


Reply to this email directly or view it on GitHub
<#156 (comment)
.


Reply to this email directly or view it on GitHub
#156 (comment).

Wout.
(typed on mobile, excuse terseness)

@duro
Copy link
Author

duro commented Oct 21, 2015

I have been using the debugger with breakpoints. The validate breakpoint is
hit after the onSubmit handler console log.

On Tuesday, October 20, 2015, Wout Mertens notifications@github.com wrote:

Then you should have said so from the start, saving all of us time :-)

Are you sure the validate is not running, I don't see a console log?

On Wed, Oct 21, 2015, 7:31 AM Adam Duro <notifications@github.com
javascript:_e(%7B%7D,'cvml','notifications@github.com');> wrote:

I already tried not passing onSubmit explicitly. Same issue.

So far this is appearing bug like, hence submitting an issue.

On Tuesday, October 20, 2015, Wout Mertens <notifications@github.com
javascript:_e(%7B%7D,'cvml','notifications@github.com');>
wrote:

First of all, questions should go on stackoverflow, reactiflux etc. (at
least that's the case with most projects and I think this one too)

Secondly, don't pass onSubmit to handleSubmit, it already takes care of
that. I think that's why it's behaving this way…

On Wed, Oct 21, 2015, 2:13 AM Adam Duro <notifications@github.com
javascript:_e(%7B%7D,'cvml','notifications@github.com');
<javascript:_e(%7B%7D,'cvml','notifications@github.com
javascript:_e(%7B%7D,'cvml','notifications@github.com');');>> wrote:

Here is a simple form component I have setup.

Here is the main page container:

import React, {Component} from 'react';
import LoginForm from './LoginForm';

export default class Login extends Component {

handleSubmit() {
console.log('submit');
}

render() {
return (

Login

);
}
}

And here is the LoginForm.js container/component:

import React, {Component, PropTypes} from 'react';
import {connectReduxForm} from 'redux-form';

function validateLogin(data, props) {
const errors = {};
if(!data.email || data.email.length > 0) {
errors.name = 'Required';
}
return errors;
}

@connectReduxForm({
form: 'login',
fields: ['email', 'password'],
validate: validateLogin
})
export default class LoginForm extends Component {

static propTypes = {
fields: PropTypes.object.isRequired,
handleSubmit: PropTypes.func.isRequired,
onSubmit: PropTypes.func.isRequired
}

render() {

const { fields: {email, password}, handleSubmit } = this.props;

return (

Email Address {name.error && name.touched &&
{name.error}
}
Password {password.error && password.touched &&
{password.error}
}
Submit

);
}
}

The problem I am running into is that the handleSubmit in the parent
container is getting called before the validateLogin function is
called
and validations have either happened successfuly, or not.

My expection is that the validator function would get called, and if
there
were no errors, then the handleSubmit that I passed in from the
onSubmit
prop would get called.

Am I doing something wrong, have the wrong expectation, or is this a
bug?


Reply to this email directly or view it on GitHub
#156.

Wout.
(typed on mobile, excuse terseness)


Reply to this email directly or view it on GitHub
<
#156 (comment)
.


Reply to this email directly or view it on GitHub
<#156 (comment)
.

Wout.
(typed on mobile, excuse terseness)


Reply to this email directly or view it on GitHub
#156 (comment).

@wmertens
Copy link
Contributor

Indeed the submit gets called before a final validate.
https://github.com/erikras/redux-form/blob/master/src/createReduxForm.js#L238

However the validate should have been called on change already?

@erikras not sure what the rationale is here…

On Wed, Oct 21, 2015, 7:54 AM Adam Duro notifications@github.com wrote:

I have been using the debugger with breakpoints. The validate breakpoint is
hit after the onSubmit handler console log.

On Tuesday, October 20, 2015, Wout Mertens notifications@github.com
wrote:

Then you should have said so from the start, saving all of us time :-)

Are you sure the validate is not running, I don't see a console log?

On Wed, Oct 21, 2015, 7:31 AM Adam Duro <notifications@github.com
javascript:_e(%7B%7D,'cvml','notifications@github.com');> wrote:

I already tried not passing onSubmit explicitly. Same issue.

So far this is appearing bug like, hence submitting an issue.

On Tuesday, October 20, 2015, Wout Mertens <notifications@github.com
javascript:_e(%7B%7D,'cvml','notifications@github.com');>
wrote:

First of all, questions should go on stackoverflow, reactiflux etc.
(at
least that's the case with most projects and I think this one too)

Secondly, don't pass onSubmit to handleSubmit, it already takes care
of
that. I think that's why it's behaving this way…

On Wed, Oct 21, 2015, 2:13 AM Adam Duro <notifications@github.com
javascript:_e(%7B%7D,'cvml','notifications@github.com');
<javascript:_e(%7B%7D,'cvml','notifications@github.com
javascript:_e(%7B%7D,'cvml','notifications@github.com');');>> wrote:

Here is a simple form component I have setup.

Here is the main page container:

import React, {Component} from 'react';
import LoginForm from './LoginForm';

export default class Login extends Component {

handleSubmit() {
console.log('submit');
}

render() {
return (

Login

);
}
}

And here is the LoginForm.js container/component:

import React, {Component, PropTypes} from 'react';
import {connectReduxForm} from 'redux-form';

function validateLogin(data, props) {
const errors = {};
if(!data.email || data.email.length > 0) {
errors.name = 'Required';
}
return errors;
}

@connectReduxForm({
form: 'login',
fields: ['email', 'password'],
validate: validateLogin
})
export default class LoginForm extends Component {

static propTypes = {
fields: PropTypes.object.isRequired,
handleSubmit: PropTypes.func.isRequired,
onSubmit: PropTypes.func.isRequired
}

render() {

const { fields: {email, password}, handleSubmit } = this.props;

return (

Email Address {name.error && name.touched &&
{name.error}
}
Password {password.error && password.touched &&
{password.error}
}
Submit

);
}
}

The problem I am running into is that the handleSubmit in the
parent
container is getting called before the validateLogin function is
called
and validations have either happened successfuly, or not.

My expection is that the validator function would get called, and
if
there
were no errors, then the handleSubmit that I passed in from the
onSubmit
prop would get called.

Am I doing something wrong, have the wrong expectation, or is this
a
bug?


Reply to this email directly or view it on GitHub
#156.

Wout.
(typed on mobile, excuse terseness)


Reply to this email directly or view it on GitHub
<
#156 (comment)
.


Reply to this email directly or view it on GitHub
<
#156 (comment)
.

Wout.
(typed on mobile, excuse terseness)


Reply to this email directly or view it on GitHub
<#156 (comment)
.


Reply to this email directly or view it on GitHub
#156 (comment).

Wout.
(typed on mobile, excuse terseness)

@erikras
Copy link
Member

erikras commented Oct 21, 2015

Sync validation is called on every render. Or at least it should be.

@wmertens
Copy link
Contributor

apart from that, why does the validate get called after submitting in
handleSubmit? Why not before or why at all?

On Wed, Oct 21, 2015 at 3:56 PM Erik Rasmussen notifications@github.com
wrote:

Sync validation is called on every render. Or at least it should be.


Reply to this email directly or view it on GitHub
#156 (comment).

Wout.
(typed on mobile, excuse terseness)

@duro
Copy link
Author

duro commented Oct 21, 2015

@erikras I can understand validation running on every render, but what I don't understand is why the submit handler is being called before validation.

It should work like this:

Submit Click -> Validation Fail -> Render
or
Submit Click -> Validation Success -> Submit Handler -> Render

Right now it is working like:

Submit Click -> Submit Handler -> Validation Success/Fail -> Render

Doesn't make sense since the submit handler should only run if the form is valid.

@duro
Copy link
Author

duro commented Oct 21, 2015

This was primarily user error. My validation rules were always telling redux-form that the form was valid.

@erikras
Copy link
Member

erikras commented Oct 21, 2015

😆 Okay, no problem. My change won't break anything.

@tylercollier
Copy link

In my case, onSubmit appeared to be called immediately in a test method. After scratching my head for a while, I noticed the number of tests being run was not the number I expected, and realized that other test files were being run, and it was another test, working as expected, which was submitting the form. The reason I was so confused is that I was using mocha's .only functionality to limit just the tests in my current describe block. It turns out this is a known bug/behavior.

sauloperez added a commit to coopdevs/katuma-web that referenced this issue Jan 14, 2017
The field-level validation it doesn't work. The onSubmit handler is
called before the validation which seems wrong. There was already an
issue on the repo about it:
redux-form/redux-form#156 but with no specific
solution.

This reuses the required validation function to validate all fields of
the form, which does happend before onSubmit is called.
@lock
Copy link

lock bot commented Jun 3, 2018

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Jun 3, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants