T
TanStack3h ago
sunny-green

linked fields, source field validation uses stale linked values

i have this linked field logic, and for some reason i can't figure out how to get the validation trigger to use the newly set values. i'm able to get around this by, instead of using linked fields, in the source field i just manually set the values there. everything works great then, but it's a bit unergonomic because this is an array field, so i have to manually iterate over each array entry and setFieldValue
<form.api.AppField
key={split.memberUserId + view.value}
name={`splits[${index}].${view.value}`}
validators={{
onChangeListenTo: ["amount"],
onChange: (context) => {
if (view.value === "percent") {
const percent =
splitFieldContext.state.value.percent;
const total =
splitFieldContext.form.state.values.amount;

const updateFn = updateSplit({
key: "percent",
value: percent,
total: total
});

splitFieldContext.setValue(updateFn);
}
// seemingly no matter how i trigger validation here,
// the values set above ^ are not used during validation
// although i see updated values in form state and ui
form.validateSomehowOrAnother()
},
}}
children={(fieldContext) => (
<div key={view.value} className="space-y-2"><fieldContext.SheetSplitField ... /></div>
)}
/>
<form.api.AppField
key={split.memberUserId + view.value}
name={`splits[${index}].${view.value}`}
validators={{
onChangeListenTo: ["amount"],
onChange: (context) => {
if (view.value === "percent") {
const percent =
splitFieldContext.state.value.percent;
const total =
splitFieldContext.form.state.values.amount;

const updateFn = updateSplit({
key: "percent",
value: percent,
total: total
});

splitFieldContext.setValue(updateFn);
}
// seemingly no matter how i trigger validation here,
// the values set above ^ are not used during validation
// although i see updated values in form state and ui
form.validateSomehowOrAnother()
},
}}
children={(fieldContext) => (
<div key={view.value} className="space-y-2"><fieldContext.SheetSplitField ... /></div>
)}
/>
11 Replies
extended-salmon
extended-salmon3h ago
I'm not sure I understand what you're trying to do. You want to change the value of a different field that is being validated? And do that transform before it is validated?
sunny-green
sunny-greenOP3h ago
field a changes field b changes based on the change to field a (I thought this is the point of linked fields) form is validated after both of ^ are finished, so we're validating on the most recent state
extended-salmon
extended-salmon3h ago
well, you have two ways to go about it: 1. use listeners for changing field b, you can attach it to field a if it's easier to follow the logic this way. Then call form.validateField('b', 'change') to trigger the validation (until this PR is merged). Field b will simply have an onChange validator. 2. in field b, use onChangeListenTo to listen to a. On change, transform the value and validate using that output.
sunny-green
sunny-greenOP3h ago
I think in the snippet above (2) is what i'm doing but i can't get the form validation to work in (2). it's operating on stale values for field b when manually triggering validation
extended-salmon
extended-salmon3h ago
you're affecting the value, but you're not using it in the validation you're setting to a new value, yes, but then you're not using the value you have right there to do the validation you need and you risk getting into a loop where validators for field b will end up in a cycle of setting itself so I don't recommend adding that in validators. A listener is safer
sunny-green
sunny-greenOP3h ago
so i don't understand what you mean that i'm not using it in the validation. when i try calling like form.validate('change'), it does validate, just on the old values for field b i do take the point that listeners is probably safer due to potential looping
extended-salmon
extended-salmon2h ago
You have * Take old value * Transform to new value, const newValue * Set the new value * Validate You have access to newValue already this assumes the field validator is the concern here if it's the form validator or the like, then the listener approach should also fix this
sunny-green
sunny-greenOP2h ago
I need validate the field yea, but all the validation logic lives in the schema Are you saying I should manually validate rather than just calling validation on the form? Like I don’t follow the “you have access to the newValue already” piece. Why does that matter?
extended-salmon
extended-salmon2h ago
it was all with the assumption that you're trying to have a field validator. The more I look at your snippet though, the more I realize that you're really just looking for listeners instead of validators let me know if the listener fixes the issue
sunny-green
sunny-greenOP2h ago
Ok I’ll try that. I feel like maybe this could be mentioned in linked fields docs- when I read the concept of that it sounds like what I’m looking for, but it actually likely isn’t
extended-salmon
extended-salmon2h ago
yeah, it's not for this case at all. It's meant for field validators that depend on other fields. But you use a form-level schema. Every field is going to run it, so there's no reason to listen to specific ones. What you do need however is to have a side effect from one field (changing the other). So that's where listeners come in

Did you find this page helpful?