T
TanStack12mo ago
fair-rose

Validation that returns additional data

I have a validation that returns additional data and I'm not sure where to put it best. I collect an Address: (Street, PostalCode, City) - I run basic validations against it onChange (fields are required) onSubmit I run the onSubmitAsync validator on the FormApi - this makes a call against the Backend and returns an array of possible address matches for what the user entered.
[
{
street: "Mainstreet 1",
postalCode: "123",
city: "Paris",
id: "4711" // <----- this is what i need later on
},
{
// … another address …
},
]
[
{
street: "Mainstreet 1",
postalCode: "123",
city: "Paris",
id: "4711" // <----- this is what i need later on
},
{
// … another address …
},
]
Multiple Adresses => Invalid => user needs to select one of them No Adress => Invalid => user needs to enter a different address 1 Match => Valid => remember the id as it's needed in onSubmit to pass it on to the following process Where would you put the id? into the form as a hidden input? into a useState? …?
3 Replies
fair-rose
fair-roseOP12mo ago
I went with the setState version:
onSubmitAsync: myZodSchema.refine(async (data) => {
const addresses = await queryClient.fetchQuery(
getVerifiedLocations(queryClient, data.location)
);

setValidatedAddresses(addresses); // React.useState()

if (addresses.length === 1) return true;

// handle 0 and multiple cases

return false;
}, { message: "A validated address is needed" })
onSubmitAsync: myZodSchema.refine(async (data) => {
const addresses = await queryClient.fetchQuery(
getVerifiedLocations(queryClient, data.location)
);

setValidatedAddresses(addresses); // React.useState()

if (addresses.length === 1) return true;

// handle 0 and multiple cases

return false;
}, { message: "A validated address is needed" })
onSubmit: async ({ value }) => {
// use validatedAddresses from React.useState() here
}
onSubmit: async ({ value }) => {
// use validatedAddresses from React.useState() here
}
the thing that's not as nice is that I'm not typesafe that validatedAddresses is in the correct state in the onSubmit (it's undefined by default)
national-gold
national-gold12mo ago
I'd use a useRef, not a setState But also, and this might just be me - this feels like a code smell in your project You're creating a conditional side effect that has statefulness during a validation check. That seems like a huge "uh oh" to get to that point
fair-rose
fair-roseOP12mo ago
Seems like useState is "too slow" after all… Now I went for fetchQuery in both the onSubmit and onSubmitAsync-Validation
const validatedAddresses = await queryClient.fetchQuery(
getVerifiedLocations(queryClient, location),
);
const validatedAddresses = await queryClient.fetchQuery(
getVerifiedLocations(queryClient, location),
);
Yeah… I don't really like the solution. Having this in the onSubmit doesn't feel good…
if (validatedAddresses.length !== 1) {
// this should never happen because the form is validated before submitting
throw new Error("No validated addresses available");
}
if (validatedAddresses.length !== 1) {
// this should never happen because the form is validated before submitting
throw new Error("No validated addresses available");
}

Did you find this page helpful?