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

Field Array Validation Not Refreshing Properly When Field is Removed #629

Open
wscullen opened this issue Mar 18, 2024 · 5 comments
Open

Comments

@wscullen
Copy link

Describe the bug

When multiple fields are added to a field array, and there is validation errors, if you update one of these fields to not have a validation error, and remove a field with a validation error (i - 1 to the good field), the removed field's validation error is applied to the field that does not have validation errors. It seems as though validation (or form state) is not properly re-evaluated and updated when a field is removed from a field array. Due to this bug, a call to form.validateAllFields("change") was attempted as a work around, but this results in the following error:

@tanstack_react-form.js?v=4b8d5915:1011 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'errorMap')
    at @tanstack_react-form…?v=4b8d5915:1011:25
    at functionalUpdate (@tanstack_react-form…s?v=4b8d5915:303:42)
    at @tanstack_react-form…s?v=4b8d5915:753:22
    at Store.setState (@tanstack_react-form…?v=4b8d5915:274:118)
    at FormApi.setFieldMeta (@tanstack_react-form…s?v=4b8d5915:748:18)
    at FieldApi.setMeta (@tanstack_react-form…s?v=4b8d5915:986:43)
    at @tanstack_react-form…?v=4b8d5915:1008:18
    at Store.batch (@tanstack_react-form.js?v=4b8d5915:292:7)
    at FieldApi.validateSync (@tanstack_react-form…s?v=4b8d5915:995:23)
    at FieldApi.validate (@tanstack_react-form…?v=4b8d5915:1106:35)
blitz.810981ba.js:352 

To view this error in the linked example project, uncomment out the indicated line 63 in the Form component.

Your minimal, reproducible example

https://stackblitz.com/edit/vitejs-vite-81fflp?file=src%2Fcomponents%2FForm.tsx

Steps to reproduce

  1. Add three people fields to the field array
  2. Click Submit to trigger validation
  3. Change the 3rd person's name to a valid value (any string), the validation error for that field will go away
  4. Remove the 2nd person from the field array by clicking the X

Result is the 2nd person (which was the 3rd person) now has the validation error showing of the previously deleted 2nd person.

To see the error, call form.validateAllFields("change") immediately after removing the field from the field array.

Expected behavior

I expect to see all validation for the 2nd person (previously the 3rd person) to continue to not have any errors, instead I'm seeing the previous validation error for the original 2nd person (which was removed).

When trying to work around the issue by manually revalidating all fields with form.validateAllFields("change") after the field is removed, errors are thrown (see above). This error can be avoided if the form.validateAllFields("change") call is placed in a setTimeout.

How often does this bug happen?

Every time

Screenshots or Videos

No response

Platform

macOS 12.7.2
chrome Version 122.0.6261.129 (Official Build) (arm64)

TanStack Form adapter

react-form

TanStack Form version

v0.16.0

TypeScript version

5.2.2

Additional context

No response

@fulopkovacs
Copy link
Contributor

Looks like we have a bug here, I'll check it out later this week! ☺️

@fulopkovacs
Copy link
Contributor

@crutchcorn You worked a lot on array fields, so I'll summon you to ask for help! 😆

If you check the video recording below, there are subfields in form.fieldMeta:

  • "people[0].name"
  • "people[1].name"

When we delete "people[0].name", the values in form.values are updated properly, but the meta data in form.fieldMeta do not, because "people[0].name" stays the same (instead of getting the value of "people[1].name"), and "people[1].name" simply gets deleted.

Kapture.2024-03-24.at.22.07.36.mp4

I could dig deeper, but I thought maybe you could give me some pointers here since you've worked with array fields recently. ☺️

@crutchcorn
Copy link
Member

@fulopkovacs do you think this is in part due to this? #662

@fulopkovacs
Copy link
Contributor

fulopkovacs commented May 18, 2024

@fulopkovacs do you think this is in part due to this? #662

They might be related, but I tested the PR of the supposed fix for #662 (#700), and it seems like it does not solve the issue.

I'll look into it! (Thanks to #656, I'm much more comfortable with working on validation-related issues 🤣 )

@fulopkovacs
Copy link
Contributor

Ok, I found the bug and made a fix locally, I will try to clean it up and commit it this week.

The main source of the problem is that the array field is not re-validated after one of its subfields gets removed. But, here are some interesting things that I found when I was investigating the issue:

  • calling validate() on the array field itself did not re-validate the subfields (not sure if it's by accident or design), so I tried using validateAllFields() to quickly get the job done
  • validateAllFields() didn't work, because the fieldInfo property of FormApi still contained data related to the deleted field, and validateAllFields() relies on it to get the fields that should be validated
  • another fun fact: since the removeValue() method of FieldApi doesn't have an opts arg ({touch: boolean}), it can't pass it to this.form.removeFieldValue, which prevents the array field's meta data from being updated (it should happen here, it's fixed in Fix/array field options #701 )

The fix I have locally deletes the data related to the last subfield from this.fieldInfo in removeFieldValue() before calling validateAllFields. This way we don't have errors and everything gets updated properly.

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

No branches or pull requests

3 participants