Optimistic update from action?
I have an action that invokes a mutation. What is the best way to optimistically update the cache for the queries affected by the action-invoked mutation client side?
5 Replies
Sorry, calling actions with optimistic updates isn't supported right now. It's definitely a limitation with calling actions from the client. Because actions can run multiple mutations, take a long time, etc it's hard for us to build correct optimistic updates here.
Some ideas on workarounds:
If possible, could you restructure your code as a mutation that schedules an action for the work that can't be done in the mutation? Then you can apply an optimistic update to the mutation on the client.
If thats not an option, can you handle this manually in your React components? I'm imagining that you set some state along with firing the action and roll that state back when the action completes (the promise resolves).
Happy to brainstorm more if you want to share more details about your use case. Sorry again, I know this is a pain.
Unfortunately these paths arent viable.
The client is getting an oauth authorization code, which needs to be exchanged for an access token along with the client secret on the backend.
This needs to be done prior to the mutation executing, persisting the access token for the user.
The desire is to have the client optimistically update that the mutation has been done to reflect the oauth flow has been successfully completed.
Got it. And is this a single mutation thats fired after the action or could it be one of many mutations?
Not knowing your React components, maybe there is still a way to set some state like
savingAccessToken: true
when the action is fired and rolled back when it completes? Then components know this is happening and render appropriate UI? Definitely hacky.
One other idea from @Indy is that you could persist this state to Convex. In this model, your users
table could have a property like savingAccessToken: v.boolean()
. Then the client could:
1. Fire a saveAccessToken
mutation and use an optimistic update to set savingAccessToken: true
2. On the server, the mutation will set savingAccessToken
and schedule an action
3. The action will get the access token and run a mutation to save it and set savingAccessToken: false
In this way, the client can look at user.savingAccessToken
and know when we're in this flow. Kinda annoying though that this creates a new state in your database to represent what is really only a client concern.You could get close by setting the state back after awaiting the action, but there could be a transient network error or the results may not be delivered by the time the action resolves (or will likely be delivered before the action resolves)
I can hack around it. Its not a big deal. I am just using convex cache for a lot of my application state, and this is one area. The action does a single mutation. Perhaps you can expose cache getters in setters through a
useConvexCache
hook where I could make potentially dangerous transformations around certain actions.