Calling dependent queries declaratively and imperatively
Hi, is there any good way to be able to call dependent queries both via hooks and imperatively? For independent queries, it's great that you can do this
but for dependent queries, I end up having to write it three times
const projectsOpts = (userId: string) => ({
queryKey: ['user', userId, 'projects'],
queryFn: () => fetchProjects(userId),
})
useQuery(projectsOpts('123'))
useSuspenseQuery(projectsOpts('123'))
queryClient.fetchQuery(projectsOpts('123'))const projectsOpts = (userId: string) => ({
queryKey: ['user', userId, 'projects'],
queryFn: () => fetchProjects(userId),
})
useQuery(projectsOpts('123'))
useSuspenseQuery(projectsOpts('123'))
queryClient.fetchQuery(projectsOpts('123'))but for dependent queries, I end up having to write it three times
const collaboratorsOpts = (projectId: string) => ({
queryKey: ['project', projectId, 'collaborators'],
queryFn: () => fetchCollaborators(projectId),
})
// Hook version
function useAllCollaborators(userId: string) {
const {data: projects} = useQuery(projectsOpts(userId))
return useQueries({
queries: projects?.map(p => collaboratorsOpts(p.id)),
})
}
// Suspense hook
function useAllCollaboratorsSuspense(userId: string) {
const {data: projects} = useSuspenseQuery(projectsOpts(userId))
return useSuspenseQueries({
queries: projects.map(p => collaboratorsOpts(p.id)),
})
}
// Imperative version
async function fetchAllCollaborators(
qc: QueryClient,
userId: string,
) {
const projects = await qc.fetchQuery(projectsOpts(userId))
return await Promise.all(
projects.map(p =>
qc.fetchQuery(collaboratorsOpts(p.id))
)
)
}const collaboratorsOpts = (projectId: string) => ({
queryKey: ['project', projectId, 'collaborators'],
queryFn: () => fetchCollaborators(projectId),
})
// Hook version
function useAllCollaborators(userId: string) {
const {data: projects} = useQuery(projectsOpts(userId))
return useQueries({
queries: projects?.map(p => collaboratorsOpts(p.id)),
})
}
// Suspense hook
function useAllCollaboratorsSuspense(userId: string) {
const {data: projects} = useSuspenseQuery(projectsOpts(userId))
return useSuspenseQueries({
queries: projects.map(p => collaboratorsOpts(p.id)),
})
}
// Imperative version
async function fetchAllCollaborators(
qc: QueryClient,
userId: string,
) {
const projects = await qc.fetchQuery(projectsOpts(userId))
return await Promise.all(
projects.map(p =>
qc.fetchQuery(collaboratorsOpts(p.id))
)
)
}