T
TanStack5mo ago
fascinating-indigo

Clearing errors for linked fields

https://stackblitz.com/edit/tanstack-form-jgfxxqwd?file=src%2Findex.tsx Repro of issues on stackblitz: Issue 1 Toggle 'show people' to true Add a couple of people with no name Press submit and receive errors Toggle 'show people' to false (this sets the people array back to []) Still can't submit Toggle 'show people' back to true Add people and see the errors are still present Issue 2 Toggle 'show people' to true Add 2 people Add a name for the second person Toggle 'show people' to false Submit - note submit fails for value being undefined for the field you had a name in (you can try adding value?.trim for the validation, but this will actually give you an error that name is required for the field you actually entered a value for!) --- I have a form where there are toggles that should reset the hidden fields or at least not check validation on those hidden fields so the form can submit. Conditionally rendering these fields does not seem to matter, which is fine but I seem to be running into issues such as the above when trying to work around it.
Keelan
StackBlitz
Form Array Example (forked) - StackBlitz
Run official live example code for Form Array, created by Tanstack on StackBlitz
25 Replies
fascinating-indigo
fascinating-indigoOP5mo ago
Something like this? Not currently working, either because of my syntax or because the validation is on the individual row.
<form.Field
name="showPeople"
listeners={{
onChange: () => {
form.setFieldValue('people', []);
form.setFieldMeta('people', (meta) => ({
...meta,
errorMap: {},
errors: [],
}));
},
}}
>
<form.Field
name="showPeople"
listeners={{
onChange: () => {
form.setFieldValue('people', []);
form.setFieldMeta('people', (meta) => ({
...meta,
errorMap: {},
errors: [],
}));
},
}}
>
sensitive-blue
sensitive-blue5mo ago
listeners={{
onChange: () => {
form.setFieldValue('people', []);
+ form.validateField('people', 'change');
},
}}
listeners={{
onChange: () => {
form.setFieldValue('people', []);
+ form.validateField('people', 'change');
},
}}
fascinating-indigo
fascinating-indigoOP5mo ago
That seems promising, but the errors are still appearing for me. Is it perhaps because the validation is on the individual row?
name={`people[${i}].name`}
name={`people[${i}].name`}
Ah, yes, when I change it to form.validateField('people[0].name', 'change'); it works. Interesting. It still fails to submit though, same error as issue 2 above.
sensitive-blue
sensitive-blue5mo ago
Pascal Küsgen
StackBlitz
Form Array Example (forked) - StackBlitz
Run official live example code for Form Array, created by Tanstack on StackBlitz
sensitive-blue
sensitive-blue5mo ago
Can you reproduce your errors here?
fascinating-indigo
fascinating-indigoOP5mo ago
https://jumpshare.com/v/ShKX4qXROHm9UKMbRGlr I believe so, submit still disabled and fields showing errors
Jumpshare
GIF Recording 2025-04-11 at 1.07.50 PM.gif
Shared with Jumpshare
sensitive-blue
sensitive-blue5mo ago
<form.Field
name="showPeople"
listeners={{
onChange: ({ fieldApi }) => {
const { values } = fieldApi.form.state;

for (const [index, _] of values.people.entries()) {
form.deleteField(`people[${index}]`);
}

form.validateField('people', 'change');
},
}}
>
<form.Field
name="showPeople"
listeners={{
onChange: ({ fieldApi }) => {
const { values } = fieldApi.form.state;

for (const [index, _] of values.people.entries()) {
form.deleteField(`people[${index}]`);
}

form.validateField('people', 'change');
},
}}
>
my stackblitz should be updated as well But yeah… should TSF handle setting a value to [] by removing all children?
adverse-sapphire
adverse-sapphire5mo ago
perhaps a helper for it would be wise .clearValues() or something basically .removeValue() for all of them thoughts?
sensitive-blue
sensitive-blue5mo ago
Why would someone want to keep the children when setting the value to an empty array? The current behavior seems unintended to me. Test for the FormApi.spec.ts (fails)
it('should delete fields when resetting an array field to an empty array', () => {
const form = new FormApi({
defaultValues: {
items: ['item1', 'item2', 'item3'],
},
});

form.mount();

// Ensure the initial state has the fields
expect(form.getFieldValue('items')).toEqual(['item1', 'item2', 'item3']);

// Reset the field to an empty array
form.setFieldValue('items', []);

// Verify that the field value is now an empty array
expect(form.getFieldValue('items')).toEqual([]);

// Verify that the fields are deleted
expect(Object.keys(form.fieldInfo).some((key) => key.startsWith('items'))).toBe(false);
});
it('should delete fields when resetting an array field to an empty array', () => {
const form = new FormApi({
defaultValues: {
items: ['item1', 'item2', 'item3'],
},
});

form.mount();

// Ensure the initial state has the fields
expect(form.getFieldValue('items')).toEqual(['item1', 'item2', 'item3']);

// Reset the field to an empty array
form.setFieldValue('items', []);

// Verify that the field value is now an empty array
expect(form.getFieldValue('items')).toEqual([]);

// Verify that the fields are deleted
expect(Object.keys(form.fieldInfo).some((key) => key.startsWith('items'))).toBe(false);
});
adverse-sapphire
adverse-sapphire5mo ago
it may be an issue with the setter function for arrays, regardless of the reaulting amount
sensitive-blue
sensitive-blue5mo ago
adverse-sapphire
adverse-sapphire5mo ago
how would you be able to tell which field was filtered out in a shorter array?
fascinating-indigo
fascinating-indigoOP5mo ago
Thanks for looking into it anyway guys, arrays were giving me the most bother when trying to implement a “listener” solution to my problem
sensitive-blue
sensitive-blue5mo ago
Can you give a code example of the issue you're thinking of? I would only want to delete the fields in the case of setting the value to an empty array
adverse-sapphire
adverse-sapphire5mo ago
setting the field from [a,b,c] to [b] would not be able to infer what values to delete so doing array updates with setFieldValue in general is dangerous with non-primitives or not using the provided array manipulation methods since it abides by the rules of react, you‘d return a completely unknown array with some values, which you can‘t easily compare with your previous values I suppose an exception can be made with an empty array, but I would recommend following the existing array manipulation methods and providing one to clear an array instead so people don‘t get the wrong idea of using setFieldValue for nested object arrays
sensitive-blue
sensitive-blue5mo ago
Good point! What should be PRed: A method that (re)sets the value to an empty array and gets rid of all the child fields + a update to the docs to mention it
adverse-sapphire
adverse-sapphire5mo ago
I would go for two methods, actually clearValues() and filterValues(callback) so that would be push, insert, clear, filter and swap I think that should cover most use cases except maybe sort, but that‘s silly to do with object arrays we can bring this up on the PR, I‘m on mobile atm but I can write something later
fascinating-indigo
fascinating-indigoOP5mo ago
Would it then be unadvisable to use setFieldValue on an array?
adverse-sapphire
adverse-sapphire5mo ago
try to avoid it if you can or remember to redo validation and meta for the field
fascinating-indigo
fascinating-indigoOP5mo ago
Okay thanks 😀
adverse-sapphire
adverse-sapphire5mo ago
do you mind if I commit to it as well? I could tinker with the implementations later today
sensitive-blue
sensitive-blue5mo ago
Not at all, go ahead!
adverse-sapphire
adverse-sapphire5mo ago
good news, I'm fairly close to implementing filterValues. Just gotta figure out the meta shift shenanigans

Did you find this page helpful?