T
TanStack8mo ago
magic-amber

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
magic-amber
magic-amberOP8mo 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: [],
}));
},
}}
>
stormy-gold
stormy-gold8mo ago
listeners={{
onChange: () => {
form.setFieldValue('people', []);
+ form.validateField('people', 'change');
},
}}
listeners={{
onChange: () => {
form.setFieldValue('people', []);
+ form.validateField('people', 'change');
},
}}
magic-amber
magic-amberOP8mo 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.
stormy-gold
stormy-gold8mo ago
Pascal Küsgen
StackBlitz
Form Array Example (forked) - StackBlitz
Run official live example code for Form Array, created by Tanstack on StackBlitz
stormy-gold
stormy-gold8mo ago
Can you reproduce your errors here?
magic-amber
magic-amberOP8mo 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
stormy-gold
stormy-gold8mo 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?
foreign-sapphire
foreign-sapphire8mo ago
perhaps a helper for it would be wise .clearValues() or something basically .removeValue() for all of them thoughts?
stormy-gold
stormy-gold8mo 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);
});
foreign-sapphire
foreign-sapphire8mo ago
it may be an issue with the setter function for arrays, regardless of the reaulting amount
stormy-gold
stormy-gold8mo ago
foreign-sapphire
foreign-sapphire8mo ago
how would you be able to tell which field was filtered out in a shorter array?
magic-amber
magic-amberOP8mo 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
stormy-gold
stormy-gold8mo 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
foreign-sapphire
foreign-sapphire8mo 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
stormy-gold
stormy-gold8mo 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
foreign-sapphire
foreign-sapphire8mo 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
magic-amber
magic-amberOP8mo ago
Would it then be unadvisable to use setFieldValue on an array?
foreign-sapphire
foreign-sapphire8mo ago
try to avoid it if you can or remember to redo validation and meta for the field
magic-amber
magic-amberOP8mo ago
Okay thanks 😀
foreign-sapphire
foreign-sapphire8mo ago
do you mind if I commit to it as well? I could tinker with the implementations later today
stormy-gold
stormy-gold8mo ago
Not at all, go ahead!
foreign-sapphire
foreign-sapphire8mo ago
good news, I'm fairly close to implementing filterValues. Just gotta figure out the meta shift shenanigans

Did you find this page helpful?