I am trying to do optimistic updates with rtk query but it is not working. I have a twitter clone where when i like a tweet i want it to do it using optimistic update so that it is instantly reflected on the UI. So what i do is i check if a post is liked and if it is display a red heart otherwise a white heart. But if i click like it is not appearing instanlty. Only when i refresh the page it shows that i have liked it. So that means optimistic updates isn't working. Can anyone tell me how to get it to work??
postSlice.ts likeTweet query
likeTweet:build.mutation({
async queryFn({id,currUserId}):Promise<any>{
try{
let likedDocRef = doc(db,`tweets/${id}`);
updateDataFirebase(likedDocRef,'likedBy',currUserId)
return {data:'ok'}
}
catch(err){
return {error:err}
}
},
async onQueryStarted({id,currUserId}, { dispatch, queryFulfilled }) {
const patchResult = dispatch(
apiSlice.util.updateQueryData<string>('getPosts', undefined, (draft:Posts[]) => {
console.log(draft)
const post = draft.find(post => post.id === id)
if (post) {
post?.likedBy.push(currUserId)
}
console.log(post)
})
)
console.log(patchResult)
try {
await queryFulfilled
} catch {
patchResult.undo()
}
}
})
getPosts
getPosts: build.query<Posts[],void>({
async queryFn(currUserId):Promise<any>{
try{
let followingsArr=await getFollowingArrFirebase(currUserId);
let tweetsArr: { }[]=[];
const q=query(collection(db,'tweets'), where("creatorId", "in" , followingsArr))
tweetsArr=await getDataFirebase(q)
//console.log(tweetsArr)
return { data:tweetsArr }
}
catch(err:any){
return{error:err}
}
},providesTags: ['Posts']})
Fetching and updating data from firestore util functions
export const getDataFirebase=async (q:any)=>{
const querySnapshot = await getDocs(q)
return querySnapshot.docs.map((doc)=> ({id: doc.id, ...doc.data() as object}))
}
export const updateDataFirebase=async (docRef:DocumentReference,property:string,id:string)=>{
let docData=(await getDoc(docRef)).data();
let arr=docData?.[property]??[];
//console.log(arr,docData?.[property]);
if(arr.includes(id)) arr=arr.filter(itemId=>itemId!=id);
else arr.push(id);
await updateDoc(docRef,property,arr);
}
i was using a query key in getPosts() but was not specifying it in the
apiSlice.util.updateQueryData<string>('getPosts', undefined, (draft:Posts[]) => {}
It should instead be
apiSlice.util.updateQueryData<string>('getPosts', currUserId, (draft:Posts[]) => {}