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

[BUG] When using zodValidator, even if I set a valid value with setFieldValue, canSubmit does not become true #999

Open
koki-iwaizumi opened this issue Oct 30, 2024 · 3 comments
Labels
bug good first issue Good for newcomers

Comments

@koki-iwaizumi
Copy link

koki-iwaizumi commented Oct 30, 2024

Describe the bug

When using zodValidator, even if I set a valid value with setFieldValue, canSubmit does not become true

import { zodValidator } from '@tanstack/zod-form-adapter'
import { z } from 'zod'

// ...

const formSchema = z.object({
  age:   z.string().optional().refine((data) => data != null && data !== '' && !isNaN(Number(data))),
  ageSub:   z.string().optional().refine((data) => data != null && data !== '' && !isNaN(Number(data))),
})

const form = useForm({
  validatorAdapter: zodValidator(),
  validators: {
    onChange: formSchema
  },
})

const onChangeAge = (handleChange) => (event: React.ChangeEvent<HTMLInputElement>) => {
  handleChange(event.target.value)
  form.setFieldValue('ageSub', event.target.value)  // The validation for ageSub is not being executed here.
}

return (
  <form>
      <form.Field name="age">
        {(field): React.ReactNode => {
          return (
            <Input
              type="number"
              onChange={(e): void => onChangeAge(field.handleChange)}
              value={field.state.value?.toString()}
            />
          )
        }}
    </form.Field>
    <form.Subscribe
      selector={(state): { isDisabled: boolean } => {
        return { isDisabled: state.isPristine || !state.canSubmit }
      }}
    >
      {({ isDisabled }): React.ReactNode => {
        return (
          <Button isDisabled={isDisabled} >
            submit
          </Button>
        )
      }}
    </form.Subscribe>
  </form>
)

In version 0.32.0, canSubmit became true with valid values (e.g., '5' or '6'), but in version 0.33.0, canSubmit remains false.

Expected behavior

I want validation to be executed when setFieldValue is called.

How often does this bug happen?

Every time

Platform

  • OS: Mac
  • Browser: Chrome

TanStack Form adapter

react-form

TanStack Form version

v0.33.0

TypeScript version

v5.6.3

Additional context

If I execute validateField after every setFieldValue call, the validation runs and behaves as expected. However, this was not necessary in version 0.32.0. I would like to know if this behavior is intentional or a bug.

like this.

import { zodValidator } from '@tanstack/zod-form-adapter'
import { z } from 'zod'

// ...

const formSchema = z.object({
  age:   z.string().optional().refine((data) => data != null && data !== '' && !isNaN(Number(data))),
  ageSub:   z.string().optional().refine((data) => data != null && data !== '' && !isNaN(Number(data))),
})

const form = useForm({
  validatorAdapter: zodValidator(),
  validators: {
    onChange: formSchema
  },
})

const onChangeAge = (handleChange) => (event: React.ChangeEvent<HTMLInputElement>) => {
  handleChange(event.target.value)
  form.setFieldValue('ageSub', event.target.value) 

  form.validateField('ageSub', 'change')  // Execute validation here.
}

return (
  <form>
      <form.Field name="age">
        {(field): React.ReactNode => {
          return (
            <Input
              type="number"
              onChange={(e): void => onChangeAge(field.handleChange)}
              value={field.state.value?.toString()}
            />
          )
        }}
    </form.Field>
    <form.Subscribe
      selector={(state): { isDisabled: boolean } => {
        return { isDisabled: state.isPristine || !state.canSubmit }
      }}
    >
      {({ isDisabled }): React.ReactNode => {
        return (
          <Button isDisabled={isDisabled} >
            submit
          </Button>
        )
      }}
    </form.Subscribe>
  </form>
)

I think the behavior change might be due to the changes introduced in #925 , but I'm not certain.

@mfrancis107
Copy link

Adding another example, I think this is probably the same underlying issue.

https://stackblitz.com/edit/tanstack-form-gpfjb6?file=src%2Findex.tsx

In this example either (First and Last are required) or Company Name

Steps to replicate:

  • load page
  • press submit
  • all errors should be shown
  • fill out first and last name
  • We would no expect all errors to disappear

@Balastrong
Copy link
Member

I think I found the issue, anyone wants to give it a try on a PR?

The journey starts here:

if (fieldErrors) {

If the form validator has field errors they're spread into the fields, but if there are no (more) errors, nothing happens.
This means that if there are existing errors they're not removed and that's our bug.

Should be fixed on validateSync and validateAsync.

@Balastrong Balastrong added bug good first issue Good for newcomers labels Nov 26, 2024
@OrlovAlexei
Copy link

@mfrancis107 I'm trying to correct in your example. I have a question) should all 3 errors be shown until all fields are filled in?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

4 participants