Skip to content

fix(form-core): fix broken sync/async validation logic #1370

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

Conversation

juanvilladev
Copy link
Contributor

Previously we were using a cumulative field errors map maintained at the form api level.
This PR removes that data structure in favor of a errorSourceMap data structure that lives within the FieldMeta for each field. This allows shifting/removing/deleting fields to automatically keep the errorSourceMap in sync.

This will fix #1323 and prevent other bugs from being raised around validation not working after other array actions like removing, shifting, swapping, moving, etc...

Async validation & sync validation now is fully synced and thoroughly tested with the new errorSourceMap. This reduces the complexity of using the cumulative errors map significantly and fixes all the issues with validations running on the wrong fields when removing/inserting/moving/shifting array fields.

Please review when you have time!

Thanks!

Copy link

nx-cloud bot commented Apr 3, 2025

View your CI Pipeline Execution ↗ for commit 35d3c97.

Command Status Duration Result
nx affected --targets=test:sherif,test:knip,tes... ✅ Succeeded 2m 7s View ↗
nx run-many --target=build --exclude=examples/** ✅ Succeeded 22s View ↗

☁️ Nx Cloud last updated this comment at 2025-04-19 23:10:24 UTC

Copy link

pkg-pr-new bot commented Apr 3, 2025

More templates

@tanstack/angular-form

npm i https://pkg.pr.new/@tanstack/angular-form@1370

@tanstack/form-core

npm i https://pkg.pr.new/@tanstack/form-core@1370

@tanstack/lit-form

npm i https://pkg.pr.new/@tanstack/lit-form@1370

@tanstack/react-form

npm i https://pkg.pr.new/@tanstack/react-form@1370

@tanstack/solid-form

npm i https://pkg.pr.new/@tanstack/solid-form@1370

@tanstack/vue-form

npm i https://pkg.pr.new/@tanstack/vue-form@1370

@tanstack/svelte-form

npm i https://pkg.pr.new/@tanstack/svelte-form@1370

commit: 35d3c97

Copy link

codecov bot commented Apr 3, 2025

Codecov Report

Attention: Patch coverage is 98.00000% with 1 line in your changes missing coverage. Please review.

Project coverage is 88.83%. Comparing base (1399731) to head (35d3c97).
Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
packages/form-core/src/FormApi.ts 95.65% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1370      +/-   ##
==========================================
+ Coverage   88.70%   88.83%   +0.12%     
==========================================
  Files          31       31              
  Lines        1364     1379      +15     
  Branches      346      347       +1     
==========================================
+ Hits         1210     1225      +15     
  Misses        137      137              
  Partials       17       17              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@teleskop150750
Copy link

teleskop150750 commented Apr 8, 2025

It would be great to stop saving the state of fields at the form level. This leads to duplication and divergence of states.

For example, how does it do
modular-forms

@juanvilladev
Copy link
Contributor Author

It would be great to stop saving the state of fields at the form level. This leads to duplication and divergence of states.

For example, how does it do

modular-forms

Correct, that's why this PR removes the cumulativeErrorsMap which is at the form level and moves the error source to the fieldMeta. This way when the fieldMeta is shifted, moved, deleted, etc... the source remains valid.

Copy link
Member

@Balastrong Balastrong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call on moving this to the field meta, I like it!

@juanvilladev
Copy link
Contributor Author

@Balastrong thanks for the review! I believe I've resolved all of the raised comments. Additionally, I created an equivalent function for determining the new error/error source at the field level validator functions (sync/async). This way its consistent for both form level/field level!

Additionally added tests for the new function and updated existing tests to ensure we cover the missed case you mentioned.

@juanvilladev juanvilladev marked this pull request as draft April 10, 2025 03:47
@juanvilladev
Copy link
Contributor Author

juanvilladev commented Apr 10, 2025

Was manually testing #1336 and realized that for that issue the error comes from no optional chain operator being used when checking for the errorMapKey inside the errorMap dynamically:

 if (field.state.meta.errorMap[errorMapKey] !== newErrorValue)

Updated it to:

 if (field.state.meta.errorMap?.[errorMapKey] !== newErrorValue)

Had to add for both:
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition

Not sure why TS doesn't infer that the value could be undefined ¯\(ツ)/¯

Edit: Added it to two other spots as well where we access submit error key:

this.state.errorMap?.[submitErrKey]

@juanvilladev juanvilladev marked this pull request as ready for review April 10, 2025 04:22
@juanvilladev juanvilladev marked this pull request as draft April 10, 2025 04:27
@juanvilladev juanvilladev marked this pull request as ready for review April 10, 2025 04:40
Copy link
Member

@Balastrong Balastrong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's just one tiny leftover from your tests probably, everything else looks good! :D

Speaking of the optional errorMap that would be an interesting investigation if you want, to validate if we should fix it on a type level (if we accept it might be undefined) or actually on the code to prevent it being undefined at all times. That's for a new PR anyway :)

@juanvilladev juanvilladev force-pushed the fix/1323_undefined_error_map_on_array_actions branch from 829e749 to 6571c24 Compare April 19, 2025 21:11
This commit updates sync and async validation state to shift with FieldMeta

Fixes "Cannot read properties of undefined" when removing array field TanStack#1323
@juanvilladev juanvilladev force-pushed the fix/1323_undefined_error_map_on_array_actions branch from d730b22 to 35d3c97 Compare April 19, 2025 23:06
@juanvilladev
Copy link
Contributor Author

There's just one tiny leftover from your tests probably, everything else looks good! :D

Speaking of the optional errorMap that would be an interesting investigation if you want, to validate if we should fix it on a type level (if we accept it might be undefined) or actually on the code to prevent it being undefined at all times. That's for a new PR anyway :)

Updated! Thanks!

Copy link
Member

@Balastrong Balastrong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@Balastrong Balastrong merged commit 337acd8 into TanStack:main Apr 20, 2025
6 checks passed
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

Successfully merging this pull request may close these issues.

"Cannot read properties of undefined" when removing array field
3 participants