T
TanStack4mo ago
adverse-sapphire

createOptimisticAction rollback too returning in the mutationFn does nothing

and onUpdate handlers doesnt fire
export const updateRating = createOptimisticAction<{
id: number,
rating: number
}>({
onMutate: ({ id, rating }) => {
// if rating === -2
if (rating < -1) return productsCollection.delete(id)

productsCollection.update(id, (draft) => {
draft.triedNote = rating < 0 ? undefined : rating
draft.triedAt = new Date()
})
},
mutationFn: async ({ id, rating }, params) => {
const tried = await updateCollection({ id, rating })
const product = productsCollection.get(id)

return {
...product,
triedNote: tried.note,
triedAt: tried.createdAt,
}
},
})
export const updateRating = createOptimisticAction<{
id: number,
rating: number
}>({
onMutate: ({ id, rating }) => {
// if rating === -2
if (rating < -1) return productsCollection.delete(id)

productsCollection.update(id, (draft) => {
draft.triedNote = rating < 0 ? undefined : rating
draft.triedAt = new Date()
})
},
mutationFn: async ({ id, rating }, params) => {
const tried = await updateCollection({ id, rating })
const product = productsCollection.get(id)

return {
...product,
triedNote: tried.note,
triedAt: tried.createdAt,
}
},
})
18 Replies
other-emerald
other-emerald4mo ago
onUpdate only calls when you do mutations outside of an explicit transaction like this. The documentation is poor still for this but you also need to await a call to either invalidate tags or collection.utils.refetch() Nothing needs returned from the mutationFn either
adverse-sapphire
adverse-sapphireOP4mo ago
So how do I avoid the rollback ?
other-emerald
other-emerald4mo ago
It's rolling back because the optimistic state is dropped when you return from the mutationFn
adverse-sapphire
adverse-sapphireOP4mo ago
The example in the doc has a return I was thinking that it would validate if the transaction match the servers data
other-emerald
other-emerald4mo ago
If you've refetched your collection then your optimistic state will be replaced with the new server state Yeah the doc needs updated...
adverse-sapphire
adverse-sapphireOP4mo ago
There’s no other way to do it than writeUpdate ? That would be great to do something that add the data without refetching and without calling writeUpdate I think
other-emerald
other-emerald4mo ago
How would that work? Just by applying the return value?
adverse-sapphire
adverse-sapphireOP4mo ago
Transaction are only for optimistic update ?
other-emerald
other-emerald4mo ago
Yes
adverse-sapphire
adverse-sapphireOP4mo ago
If I do a writeUpdate in the mutationFn that fine ?
other-emerald
other-emerald4mo ago
A transaction is tracking the syncing of the mutation to the server and the sync back of the new server data Yup! That or just refetch everything!
adverse-sapphire
adverse-sapphireOP4mo ago
But refetch can be extensive for network sometimes
other-emerald
other-emerald4mo ago
Sure, that's why the direct write APIs exist
adverse-sapphire
adverse-sapphireOP4mo ago
Yea but that a bit redundant
other-emerald
other-emerald4mo ago
Redundancy is good 😂
adverse-sapphire
adverse-sapphireOP4mo ago
I’m gonna do a writeUpdate in the mutationFn so Not saying is not
other-emerald
other-emerald4mo ago
Refetch is the default as it's automatic and works great for most use cases. Direct writes is for everything else
adverse-sapphire
adverse-sapphireOP4mo ago
Ok ok Thx

Did you find this page helpful?