form defaultValues doesn't clear with initial data retrieved
hey all! posting my first question here in a confusing situation i'm in. I use tanstack query to fetch data from an endpoint, and tanstackform to handle em. I've a two dropdown screen, in which the second dropdown is clearable/deletable by users but i'm unable to reach that state which falls back to form.defaultValues instead of users able to remove its node completely.
What happens is that if I commented this code out
if (!country) return;
it deletes the value from the dropdown, but i'm left with my object like this:
[{"country": "AD","verId": "1"},{"country": "","verId": ""}]
and if I didn't, i'm unable to remove anything, anytimg i try to click on the delete button, it doesn't do anything and i'm left with the default values.
16 Replies
genetic-orangeOP•4mo ago
and my form field is:
<form.Field
name="taxResidencies[1].country"
validators={{
onChangeListenTo: ["taxResidencies[0].country"],
onChange: ({ value }) => {
if (!value) {
return undefined;
}
return undefined;
},
}}
>
{(field) => (
<>
<form.Subscribe selector={(state) => state.values.taxResidencies[0]?.country}>
{(primaryCountry) => (
<Dropdown
.........
onChange={(value: string | undefined) => {
if (value === undefined) {
const primaryResidency = {
country: form.getFieldValue("taxResidencies[0].country"),
taxId: form.getFieldValue("taxResidencies[0].verId"),
} as TaxResidency;
form.resetField("taxResidencies[1].country");
form.resetField("taxResidencies[1].verId");
form.setFieldValue("taxResidencies", [primaryResidency]);
}
const country = value as LegalCountries; // type of country codes e.g. "SE", "IT" ...
// if (!country) return;
const taxId = country === "ES" ? null : "";
field.form.setFieldValue("taxResidencies[1].country", country);
field.form.setFieldValue("taxResidencies[1].verId", verId);
}}
clearable={true}
/>
)}
</form.Subscribe>
</>
)}
</form.Field>
evident-indigo•4mo ago
Formatted for Discord:
So you have a structure of two dropdowns with one being completely removable?
genetic-orangeOP•4mo ago
Exactly, and thanks for the reformatting 🙂
the second dropdown is dependant on the first one, but that's not there issue so far. if I removed the default values, all of this works as expected. But after fetching the data from the enpoint and assigning it's response to the form's defaultValues, things are breaking ..
evident-indigo•4mo ago
do you have an example of what
userData
could look like?genetic-orangeOP•4mo ago
userData has many properties, but for the defaultValues at least userData.taxResidencies is:
it's a descriminated union that requires verId only for non spanish values.
evident-indigo•4mo ago
I will use that and the provided field to create a stackblitz reproduction, if that's alright
that way, it's easier for me (or others seeing this post) to edit the values and test
genetic-orangeOP•4mo ago
@Luca | LeCarbonator i tried to mock as much as I can, here we go with the issue reproduced:
https://stackblitz.com/edit/vitejs-vite-ktgdr9dv?file=src%2FApp.tsx
thanks in advance 🙂
mh4md.a@gmail.com
StackBlitz
Vitejs - Vite (forked) - StackBlitz
Next generation frontend tooling. It's fast!
evident-indigo•4mo ago
great! I'll take a look later
Some notes:
- You are calling
reset
on the field that you proceed to completely delete. There are helper methods like FormApi.deleteField
for that instead
- Your tax residencies are dependent on where they are in the array. It would probably simplify the code if you have a primaryTaxResidency
and an array of additional ones (that may be empty)
- instead of field.setValue(newValue)
, use field.handleChange(newValue)
as the latter will handle change listeners and validators for yougenetic-orangeOP•4mo ago
Thanks! I've changed to use
deleteField
instead of reset, and created two separate arrays to separate concerns of each field, used handlchange in favour of setValue in teh whole screen. Tho, I am still unable to reset back to set the additional country to undefined. It always go back to the defaultValues
provided by the endpoint, while that I understand that this might be how tanstack-form works, but is there a way to still keep the defaultValues but override a node on a trigger? none of the below functions worked so far 😦
evident-indigo•4mo ago
resetField is exactly for that, to reset the field back to the default value that was set.
If you don't like the default value provided by the endpoint, then it's not really a default value and should be set instead
overriding nodes can be done with
* deleteField
* setFieldValue
* conditionally rendering it in React
genetic-orangeOP•4mo ago
I mean i'm currently using
form.deleteField("additionalTaxResidency");
but that doesn't really override the node. May I ask for more clarity about "conditionally rendering it in React"? 🙂
neither form.setFieldValue
nor deleteField
works so far to override a value unfortunatelyevident-indigo•4mo ago
Instead of resetting / setting the additional tax residency every time the primary changes, you can also prevent the second field from being visible based on a condition.
Then in your
onSubmit
, you ignore the value based on that condition as wellgenetic-orangeOP•4mo ago
this does, I think i just need to sanitize it myself :), i'm still curious about hearing out your opinion tho 🙂
evident-indigo•4mo ago
showSecondResidency && <YourComponent/>
genetic-orangeOP•4mo ago
I really appreciate your input Luca, thanks! I think I have enough to try it out myself from here 🙇
evident-indigo•4mo ago
:PepeThumbs: