-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Always return old data even when action has errors #124
Always return old data even when action has errors #124
Conversation
🦋 Changeset detectedLatest commit: 4566651 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
9cda536
to
3720ca3
Compare
I just experimented with react query mutations and seems like they also do not keep old data/error while the mutation is pending. Furthermore, SWR does not return old data. But your layout shift in the before video is understandably annoying and the after looks much better. I'm curious if this should be an opt in thing, and what are possible negative side effects that may result from keeping errors/data while pending. |
This is what we need to find out. Can you think on any? Also keep in mind this is a validation library I think keeping errors while running is the expected behaviour |
I think the negative side is the types will be lying. When status is pending, error can be undefined or the error type. If we update the types though to tell the truth, we lose the narrowing of types using A possible solution that I am leaning towards is introducing a new variable, We can do the same with |
I'm not against having these flags. But here is my question: Why is it wrong to have errors and data while the request is happening? How can that affect existing users? How could this change break existing use cases? |
In terms of
|
Good questions, happy to share my thought processes further. Types
As of now, the type doesn't support The type for a pending status has error and data both set to undefined. {
isPending: true
isOptimistic: false
data: undefined
isError: false
error: undefined
isSuccess: false
status: "pending"
} However, this will not be an "honest type" since error and data can be defined while status is pending -- if we go this direction. The same is true for the error types and success types, since isPending can be true at the same time. We can't have dishonest types. Meaning we would need to update the types to correctly reflect that if status is pending, data or error can be defined. Breaking Changes
Since big libraries like The breaking change off the top of my head was if people used the status to determine the shape in a specific order. if (isError) {
return <div>Error: {error.code}</div>
} else if (isPending) {
return <div>Loading...</div>
} else if (isSuccess) {
return <div>Success: {JSON.stringify(data)}</div>
} This code will no longer be valid since isError and isPending can be true at the same time. People will always need to check
This PR diverges ZSA from this pattern that I think many people are used to from the big data fetching libraries. It would change to: "if the mutation is in |
Hi, we don't need to rush 😄. We can discuss this calmly because I respect what you're doing here. It's late and during the week my brain is fried so excuse me if I say nonsense 🙏 I'm playing with react-query api here Indeed they remove the error while request is flying. But even if they don't the case you put would not break no? Also in this simple example, you can see the jumpy text. I think react-query is a general purpose tool so it can have this behavior but a tool that works for data mutation in forms looks better to keep old data if you think in terms of UX for forms to avoid jumpiness. I agree types can NOT lie and should be changed. But still can't see the breaking code if we always keep data/errors while requesting. I'll think harder and read more carefully what you said. |
All good man, totally concur, no rush. I can ask some other |
I agree his video demonstrates an issue in UX and keeping the error state around might be useful in some scenarios. I wonder if an isError || hadError would be useful so that we can then expect the error property to be defined in the type? I'm not sure if that helps.
I personally didn't run into this issue because I'm using client side validation on all my forms, so the moment someone clears the top input after submitting, the error validation shows. |
Appreciate the input here @webdevcody
Yeah I think this is why the big libraries like Overall I am on board with adding something like a |
Ok, let's go with this. I'll add the flags |
With the new input schema functions that will soon be released in the next minor version, validation might not be able to be fully done on the client (as in @andresgutgon) case where I think he is checking for duplicate usernames |
Awesome. Can you make a PR into the |
You mean rebase this one with |
Nevermind, no need to point there. Just merged that one to main |
3720ca3
to
39c858d
Compare
39c858d
to
6e805a5
Compare
I made all this behavior optional on I think these are the two places I need to touch to make this change fully backward compatible. zsazsa-react |
This is how we can enable this behaviour export const onboarding = authProcedure
- .createServerAction()
+ .createServerAction({ persistedDataWhenError: true })
const { data, executeFormAction, isPending, error } = useServerAction(onboarding, {
initialData: { name, username },
+ persistedData: true,
+ persistedError: true,
|
6e805a5
to
b1e0995
Compare
This is too much imo. Forcing to implement a method
So no check? always return the rawInput. I like this if you think is not going to break existing use cases |
True, so yeah let's just add raw input to the default TZSAError. Won't break anything. The one concern is security, which is why we can't return parsed input but raw input is fine since that's what gets passed in so guaranteed nothing leaks. |
Opps! i closed by mistake
So that means zsa-react has to deal with FormData? Why is a security concern? I want to understand |
I'm thinking more about this. This is not the case no? When there is an error this input data does not arrive to the handler. Imo having this flag as part of the action configuration is clear enough. But open to change I would like to understand your concerns with security and also not returning always JSON which force |
Another thing I don't like about returning inputData in 🟢 This is how I use it now: const { data, executeFormAction, isPending, error } = useServerAction(...)
const fieldErrors = error?.fieldErrors
return (
<Input
label='Your name'
errors={fieldErrors?.name}
defaultValue={data?.name}
/>
) This api makes super nice to build pure transactional backend-only experiences 🔴 Having const { data, executeFormAction, isPending, error } = useServerAction(...)
const nameData = data?.name ?? error.rawInput?.name // Or something like this |
edffe15
to
8da516d
Compare
Hi @IdoPesok could you take a look at my comments? Everything works great now but I would love to merge this PR before merging my code |
Also, I cherry picked in your commit that fixes side effects with |
Oh good catch. So a form with an input file right? I didn't tried this case. I'll try to fix it |
82ccb7f
to
3c60709
Compare
Ok I think what we can do is to set to Screen.Recording.2024-06-29.at.10.49.47.mov |
This is useful if in the UI we use `data.my_field`. If other fields have errors but `my_field` is ok I want to keep showing it
3c60709
to
4566651
Compare
Happy to report the persist flags are available in
Trying a bit diff implementation of this. ETA 1 day. |
Happy to see it. What's the idea? |
New PR: #155. The issue with the code in this PR is that it is breaking one of the core behaviors of ZSA which is to return |
Awesome work! I'll close this and follow yours for progress |
What?
This is useful if we use
data.my_field
in the UI. If other fields have errors butmy_field
is ok I want to keep showing it.Fix this issue
#121
TODO
Current behavior
Screen.Recording.2024-06-16.at.16.55.18.mov
With these changes
Screen.Recording.2024-06-16.at.16.54.10.mov