T
TanStack•3y ago
rival-black

How to access previous data of query?

Someone that knows any best practices regarding how to manage optimistic updates and query cache with Tanstack Query? I have a mutation and onSuccess of that mutation I trigger a function called updateQueryStateOnSuccess. (Where I want to update the cache for a certain query directly so I don't have to wait for it to be updated next time I fetch it) My prevData is always undefined currently which is my main issue.
const useUpdateUserInfo = createMutation({
request: updateUserInfo,
dependentQueries: ['getUserInfo'],
updateQueryStateOnSuccess: (queryClient, data, variables) => {
queryClient.setQueryData<UserInfo>(['getUserInfo'], (prevData): UserInfo | undefined => {
console.log('prevData: ', prevData); // Undefined even if there is data in the queryCache for that queryKey

// const cache = queryClient.getQueryCache();
// console.log('cache: ', cache);
// const oldData = cache?.queriesMap?.['getUserInfo']?.state?.data?.result;
// console.log('oldData: ', oldData); // Works but ugly af

if (!prevData || !variables) {
return;
}

console.log('updating cache');
return {
...prevData,
firstName: variables.firstName,
lastName: variables.lastName,
email: variables.emailId,
phoneNumber: variables.mobileNumber,
};
});

},
});
const useUpdateUserInfo = createMutation({
request: updateUserInfo,
dependentQueries: ['getUserInfo'],
updateQueryStateOnSuccess: (queryClient, data, variables) => {
queryClient.setQueryData<UserInfo>(['getUserInfo'], (prevData): UserInfo | undefined => {
console.log('prevData: ', prevData); // Undefined even if there is data in the queryCache for that queryKey

// const cache = queryClient.getQueryCache();
// console.log('cache: ', cache);
// const oldData = cache?.queriesMap?.['getUserInfo']?.state?.data?.result;
// console.log('oldData: ', oldData); // Works but ugly af

if (!prevData || !variables) {
return;
}

console.log('updating cache');
return {
...prevData,
firstName: variables.firstName,
lastName: variables.lastName,
email: variables.emailId,
phoneNumber: variables.mobileNumber,
};
});

},
});
6 Replies
adverse-sapphire
adverse-sapphire•3y ago
if its undefined then there is no data under that query key
rival-black
rival-blackOP•3y ago
But there is, if I do this it works 🤔
updateQueryStateOnSuccess: async (queryClient, data, variables) => {
queryClient.setQueryData<UserInfoResponse>(['getUserInfo'], (prevData: UserInfoResponse | undefined) => {
console.log('prevData: ', prevData); // Undefined
const oldUserInfo = queryClient.getQueriesData<UserInfoResponse>(['getUserInfo'])?.[0]?.[1];
console.log('oldUserInfo: ', oldUserInfo);

if (!oldUserInfo || !variables) {
return;
}

console.log('updating cache');
return {
...oldUserInfo,
result: {
...oldUserInfo.result,
firstName: variables.firstName,
lastName: variables.lastName,
email: variables.emailId,
phoneNumber: variables.mobileNumber,
},
};
});
},
updateQueryStateOnSuccess: async (queryClient, data, variables) => {
queryClient.setQueryData<UserInfoResponse>(['getUserInfo'], (prevData: UserInfoResponse | undefined) => {
console.log('prevData: ', prevData); // Undefined
const oldUserInfo = queryClient.getQueriesData<UserInfoResponse>(['getUserInfo'])?.[0]?.[1];
console.log('oldUserInfo: ', oldUserInfo);

if (!oldUserInfo || !variables) {
return;
}

console.log('updating cache');
return {
...oldUserInfo,
result: {
...oldUserInfo.result,
firstName: variables.firstName,
lastName: variables.lastName,
email: variables.emailId,
phoneNumber: variables.mobileNumber,
},
};
});
},
So the data is Available in getQueriesData(['getUserInfo'])[0][1] but not for queryClient.setQueryData(['getUserInfo'], prevdata => ...
adverse-sapphire
adverse-sapphire•3y ago
getQueriesData does fuzzy matching, while getQueryData needs exact keys. There is no data for a key that is exactly ['getUserInfo'], you probably have ['getUserInfo', 'some', 'more', 'stuff'] look into the devtools, you should see all keys and entries there
rival-black
rival-blackOP•3y ago
Hmm seems like the queryKey now is ['getUserInfo', undefined] 🤔 Need some way to get the queryKey for a query I guess? queryKey: [queryName, parameters], Feels like this is the main issue, we pass in parameters when setting the queryKey for a query which we can't then know from the mutation that is trying to update it in any easy way?
adverse-sapphire
adverse-sapphire•3y ago
if you need access to the parameters, you need to make them more globally available. it's a client state management problem that's why the easiest way is just queryClient.invalidateQueries[queryName] and you don't need to worry about any of this
rival-black
rival-blackOP•3y ago
Yes because this will mean I have stale data when I come back to the screen where the query is rendered since the data has not yet been updated. hmm maybe it worked now 😂 Been overcomplicating this big time In the scenarios I can get the query parameters for the queryKey from the payload of the mutation. How should I construct it to use it? My queryKey looks like this:
["getGadgetDetails", {"objectId": "100673002", "policyId": "100673"}]
["getGadgetDetails", {"objectId": "100673002", "policyId": "100673"}]
and I have the correct values for variables.id and data?.result.policyId
objectId: 100673002
policyId: 100673
objectId: 100673002
policyId: 100673
This is what I am trying now but it is not working
['getGadgetDetails', { objectId: variables.id, policyId: data?.result.policyId }],
['getGadgetDetails', { objectId: variables.id, policyId: data?.result.policyId }],
Here is the start of the relevant code:
queryClient.setQueryData<GadgetDetailsResponse>(
['getGadgetDetails', { objectId: variables.id, policyId: data?.result.policyId }],
(prevData: GadgetDetailsResponse | undefined) => {
console.log('prevData', prevData); // undefined
queryClient.setQueryData<GadgetDetailsResponse>(
['getGadgetDetails', { objectId: variables.id, policyId: data?.result.policyId }],
(prevData: GadgetDetailsResponse | undefined) => {
console.log('prevData', prevData); // undefined
@TkDodo 🔮 If you or someone else has any ideas let me know 😄

Did you find this page helpful?