T
TanStack•11mo ago
genetic-orange

getQueryData returning undefined unless exact key match

I am trying to use one cache as the initial value for another, following https://tanstack.com/query/latest/docs/framework/react/guides/initial-query-data#initial-data-from-cache Example code
const useCustomHook = (param) => {
const queryClient = useQueryClient();

const query = useQuery({
queryKey: ['key', param],
queryFn: async () => {
return await fetchData();
},
initialData: () => {
console.log('init', queryClient.getQueryData(['key']));
return undefined;
},
});

console.log('root', queryClient.getQueryData(['key']));

return query
}
const useCustomHook = (param) => {
const queryClient = useQueryClient();

const query = useQuery({
queryKey: ['key', param],
queryFn: async () => {
return await fetchData();
},
initialData: () => {
console.log('init', queryClient.getQueryData(['key']));
return undefined;
},
});

console.log('root', queryClient.getQueryData(['key']));

return query
}
Both the init and root logs are undefined I understand on the initial query there is no data and I would expect undefined, but on changing param I still get undefined. But if I update the logs to queryClient.getQueryData(['key', param]) the cached data is returned. Am I missing a something, the docs say I should be able to get the data with only a partial key match
TanStack | High Quality Open-Source Software for Web Developers
Headless, type-safe, powerful utilities for complex workflows like Data Management, Data Visualization, Charts, Tables, and UI Components.
From An unknown user
From An unknown user
8 Replies
other-emerald
other-emerald•11mo ago
getQueryData is an exact query key match. Try getQueriesData
genetic-orange
genetic-orangeOP•11mo ago
Worked perfectly thank you, the docs related to this could do with updating
absent-sapphire
absent-sapphire•11mo ago
where do the docs mention that getQueryData can return data with a partial key matching ?
absent-sapphire
absent-sapphire•11mo ago
yes because ['todos'] is a cache entry which contains the todo list. It could be ['todos', 'list'] to make it more explicit maybe but it matches that key exactly
genetic-orange
genetic-orangeOP•11mo ago
In the example code for "Initial Data from Cache" it shows queryKey: ['todos', todoId] then to use getQueryData(['todos']) which is not an exact match for the queryKey and returns undefined
absent-sapphire
absent-sapphire•11mo ago
because it's not looking up that cache. In the example, the cache is:
['todos']: [{ todo1 }, { todo 2}]
['todos', 1]: { todo1 }
['todos', 2]: { todo2 }
['todos']: [{ todo1 }, { todo 2}]
['todos', 1]: { todo1 }
['todos', 2]: { todo2 }
so when a detail todo cache entry is created, it tries to pre-fill itself with data from the list cache you can see that it uses ?.find on the result - it cleraly expects an Array in the cache again, this example would be clearer with more detailed key structures, like:
['todos', 'list']: [{ todo1 }, { todo 2}]
['todos', 'detail', 1]: { todo1 }
['todos', 'detail', 2]: { todo2 }
['todos', 'list']: [{ todo1 }, { todo 2}]
['todos', 'detail', 1]: { todo1 }
['todos', 'detail', 2]: { todo2 }
then, it would read:
const result = useQuery({
queryKey: ['todos', 'detail', todoId],
queryFn: () => fetch(`/todos/${todoId}`),
initialData: () =>
queryClient.getQueryData(['todos', 'list'])?.find((d) => d.id === todoId),
})
const result = useQuery({
queryKey: ['todos', 'detail', todoId],
queryFn: () => fetch(`/todos/${todoId}`),
initialData: () =>
queryClient.getQueryData(['todos', 'list'])?.find((d) => d.id === todoId),
})
hope that makes sense now
genetic-orange
genetic-orangeOP•11mo ago
Okay I get what I was missing now, it's fetching the list cache not just a cache with a 'todo' key, makes perfect sense, thanks for the help getting my head round this

Did you find this page helpful?