debounce for synchronous validation?
This may be a silly question 🙂
I am wondering can I have a field level onChange validator operate on a debounce, without having to "manufacture" an async function?
The validation will be against a zod schema, I just don't want the user to have a bad UX by getting immediate feedback
55 Replies
rare-sapphire•11mo ago
You can set the number of milliseconds in
onChangeAsyncDebounceMs
and tanstack form will handle the debounce for you 🙂other-emeraldOP•11mo ago
Thanks for replying @Leonardo 🙂
So do you mean I should just put the zod schema on the onChangeAsync, even if the zod rule is not an async check?
(Sorry for basic question)
rare-sapphire•11mo ago
Give it a try if you haven't already 😄
Anyway doesn't seem wrong, if you declare that you validate after X time, technically it's no longer a sync operation
sensitive-blue•5mo ago
No this doesn't work, sadly. Standard Schema validators (Zod, etc.) are not provided as async functions, so it would be nice if we could designate a debounce time for our syncronous validators.
conscious-sapphire•5mo ago
Wouldn't that mess with meta state such as
isValidating
?
It's synchronous, but also takes a period of time depending on what you set as debounce msrare-sapphire•5mo ago
Can you please share a stackblitz where it doesn't work? In the standard schema example you can safely do this:
sensitive-blue•5mo ago
As far as I know you can only populate onChangeAsync with a solid single validator or async function. Since I am already performing an async validation I don’t think this would work for me.
Maybe there’s an easy way to do both with debounce?
I don’t know how isValidating is set, but debouncing a sync operation doesn’t require any promises so I’d assume no issue.
conscious-sapphire•5mo ago
just forked the standard schema example and passing a zod scchema to
onChangeAsync
works just fine
but yeah, if you have other async validators unrelated to schemas it becomes an issuesensitive-blue•5mo ago
Would be cool if onChangeAsync could take an array…
Probably a ridiculous thought
conscious-sapphire•5mo ago
an array of validators ... maybe? none of the validate types is an array, so it could probably be implemented as union
depends on how errors are supposed to be handled though. What if array[0] caused errors and array[1] as well? flatten the array?
rare-sapphire•5mo ago
If the library handles an array of async validators we'll get people expecting us to also handle concurrency, order, error handling (what if one fails?) & co
conscious-sapphire•5mo ago
true
rare-sapphire•5mo ago
If you have multiple checks to do on async I'd say you can handle everything in one function and implement your own logic
conscious-sapphire•5mo ago
how do standard schemas work behind the scenes? do they also just reutrn a parsed object like you can with custom functions?
if so, would a helper function for standard validators help perhaps? Something that can be called with a schema and it returns an error / null that tanstack parses as if you had given it the schema directly
rare-sapphire•5mo ago
Manually handling standard schema should be fairly simple https://github.com/TanStack/form/blob/main/packages/form-core/src/standardSchemaValidator.ts#L67-L69
conscious-sapphire•5mo ago
is that accessible from outside this file though?
the
transformIssues
I meanrare-sapphire•5mo ago
Let me doublecheck, now that we entirely removed adapters and allowed everything to be returned from validtors, transformIssues might be outdated and can be removed
Ah no wait, that's also what spreads errors in the form 🤔
standardSchemaValidators
seems to be accessible from user land, it might be enoughconscious-sapphire•5mo ago
looks like it works

conscious-sapphire•5mo ago
at least I think I used
validationSource
right
if the validation source can only be field or form, how about a method in formApi
that validates its values with a schema as argument?
formApi.somethingStandardSchemaNamedIdk(ZodSchema)
the success check would just be what the snippet above is, checking if it's undefined
rare-sapphire•5mo ago
Or even a one time validator, like you pass whatever you want on form.validateOnceWith(validator)
No, that's too much 😂
conscious-sapphire•5mo ago
yeah, I wouldn't abstract too far
it would just help for users that want special conditions to check instead of going the simple (and restricted) route of passing the schema directly
then they needn't worry about turning it into validation issues
because in the validation callback, both
value
as well as validationSource
are redundant as they are inferrable from FormApi / FieldApi
standardSchemaValidators
would still be around if you truly really needed it outside of validators, I suppose
I can make a PR for it later today if you'd likerare-sapphire•5mo ago
I can't find a decent name for this helper but I see value in the idea, yes please I'd love to discuss it on a PR!
conscious-sapphire•5mo ago
yeah, a name's difficult. If it's attached to formApi, then you can't guarantee it's only in context of validators
and it doesn't change internal state
rare-sapphire•5mo ago
Maybe looking at the implementation will help us figuring out the right name 😄
conscious-sapphire•5mo ago
GitHub
feat(FormApi): add helper method to parse values into Standard Sche...
As of tanstack form v1.4, there are two ways to use standard schemas as validators:
1. Pass directly
validators: {
onChange: mySchema
}
2. Create a callback and import standardSchemaValidators
va...
rare-sapphire•5mo ago
Quick question, do we need to differentiate between sync and async?
conscious-sapphire•5mo ago
no, as the user decides where it will be used
so they could just do
async () => formApi.validateWithSchema()
rare-sapphire•5mo ago
I mean if the schema is async
conscious-sapphire•5mo ago
oh
I'm afraid I don't know. I haven't looked into standard schemas much. Perhaps I can answer that once I looked into how it actually works behind the scenes
conscious-sapphire•5mo ago
it might be trouble, yeah

rare-sapphire•5mo ago
One more challenge, we're doing it on field too? As with field you could simply use your schema and manually handle the errors.
Speaking of form, don't we only need
prefixSchemaToErrors
to convert the object notation to how we define fields in form?conscious-sapphire•5mo ago
could you elaborate on what you mean with your first point?
standardSchemaValidators has the option to pass
field
as validationSource, so if that's not needed then the point of that parameter confuses me
I guess for this?
rare-sapphire•5mo ago
Exactly, that's inherited from the old validator adapters where you could actually pass a transform function
But now that step is useless and can be removed
conscious-sapphire•5mo ago
true, but it could help readability.
Otherwise you'll have to do
schema['~standard'].validate(value)
rare-sapphire•5mo ago
Ok, that's fair
conscious-sapphire•5mo ago
If the standard schema adapter has some stale code from before, then it could be refactored in the PR alongside those methods
rare-sapphire•5mo ago
defaultFieldTransformer can be removed for sure 😄
conscious-sapphire•5mo ago
the zod user in me just wants to call it
parseWithSchema
, but I'm not sure if that's something the standard schema uses as wordrare-sapphire•5mo ago
valibot uses parse too I think
standard schema uses
validate
, do you think it's confusing in the form context?
form.validateWithSchema.... not too convincing since we want to keep it statelessconscious-sapphire•5mo ago
yeah, that's my main issue with it
ChatGPT usually gives me solid ideas for names, but with this case it's mostly garbage
how about
diagnoseValuesWithSchema
?
inspectValuesWithSchema
:HmmNotes:
no, don't like that onerare-sapphire•5mo ago
getSchemaIssues?
No get makes me think they're already there... I'm going back to parse
conscious-sapphire•5mo ago
that might be confused with
getAllErrors()
if someone passed a schema directly as validator
I think while parse
isn't specifically related to standard schema, it describes the best that it's just taking values and running it against the schemarare-sapphire•5mo ago
Yeah, I agree
conscious-sapphire•5mo ago
I will implement it with the placeholder name
parseValuesWithSchema()
for now. There's still stuff to check such as sync / asyncrare-sapphire•5mo ago
Sounds good, thanks!
conscious-sapphire•5mo ago
ooh, these methods actually help us narrow it a bit too
since standardSchemaValidators returns
ValidationIssue[] | { form: ..., fields: ...} | undefined
but that's dependent on the source, which we know from formApi / fieldApi
alright, that should also cover some docs to explain how the methods would work. I'm only familiar with react, so I'd appreciate someone to go through angular/solid/vue to check I didn't mistype itrare-sapphire•5mo ago
Aaand there's probably a typo in React 😄
conscious-sapphire•5mo ago
there is :PepeThumbs:
of all places :curlUp:
I just noticed something. The schema can technically set errors in places that don't even have fields. Could that cause issues?
like if my schema expects
name
, but that field doesn't exist
I'll just type it like validators does :PepeThumbs:rare-sapphire•5mo ago
Nitpicking on
parseFieldValuesWithSchema
, why Field
in the name even if we don't pass a field name there?conscious-sapphire•5mo ago
initially, it was to be consistent with other methods (
FieldApi#swapValues
-> FormApi#swapFieldValues
)
but you're absolutely right. Doesn't make sense in this context :Hmm:
I guess it should just be parseValuesWithSchema
?rare-sapphire•5mo ago
Yeah, that's probably better
conscious-sapphire•5mo ago
anything else that I could amend into this commit?
rare-sapphire•5mo ago
Nah, I think I'm happy to merge after this
conscious-sapphire•5mo ago
sounds good. One sec
there we go
implemented in v1.5 :PepeThumbs:
sensitive-blue•5mo ago
You are the 🐐 for this!