T
TanStack2mo ago
rare-sapphire

How to initialize query from within a loader using data from another query?

Hey there 👋 I am currently trying to figure out how to initialize a query using data from another query within a route loader in Start. I was unsure if this Q belonged in #start-questions , #react-query-questions , or #router-questions , so if this is the wrong place I'd be glad to remove it and ask elsewhere. I originally tried ensureQueryData with initialData but this wasn't working for me. So, I figured, maybe manually setting it 🤷‍♂️ But because route loaders in Start are isomorphic this can't be right + it doesn't work...
export const Route = createFileRoute("/_main/teacher/$teacherSlug")({
loader: async ({ context, params }) => {
const teacher = await context.queryClient.ensureQueryData(
api.teachers.findProfileBySlug.queryOptions({
input: {
slug: params.teacherSlug,
},
}),
);

teacher &&
context.queryClient.setQueryData(
api.teachers.getSave.queryKey({
input: {
teacherId: teacher.id,
},
}),
() => ({
isSaved: !!teacher.saves?.length,
savedAt: teacher.saves?.[0]?.createdAt || null,
teacherId: teacher.id,
saveId: teacher.saves?.[0]?.id || null,
}),
);
return {
dehydratedState: dehydrate(context.queryClient),
};
},
component: TeacherPage,
});

function TeacherPage() {
const { dehydratedState } = Route.useLoaderData();
// ...
return (
<HydrationBoundary state={dehydratedState}>{/** ... */}</HydrationBoundary>
);
}

function SomeRandomComponentSomewhere({ teacherId }: { teacherId: string }) {
const { data: saveState } = useQuery(
// Query should be initialized
api.teachers.getSave.queryOptions({
input: {
teacherId,
},
}),
);

return <div>SSR initialized save state: {JSON.stringify(saveState)}</div>;
}
export const Route = createFileRoute("/_main/teacher/$teacherSlug")({
loader: async ({ context, params }) => {
const teacher = await context.queryClient.ensureQueryData(
api.teachers.findProfileBySlug.queryOptions({
input: {
slug: params.teacherSlug,
},
}),
);

teacher &&
context.queryClient.setQueryData(
api.teachers.getSave.queryKey({
input: {
teacherId: teacher.id,
},
}),
() => ({
isSaved: !!teacher.saves?.length,
savedAt: teacher.saves?.[0]?.createdAt || null,
teacherId: teacher.id,
saveId: teacher.saves?.[0]?.id || null,
}),
);
return {
dehydratedState: dehydrate(context.queryClient),
};
},
component: TeacherPage,
});

function TeacherPage() {
const { dehydratedState } = Route.useLoaderData();
// ...
return (
<HydrationBoundary state={dehydratedState}>{/** ... */}</HydrationBoundary>
);
}

function SomeRandomComponentSomewhere({ teacherId }: { teacherId: string }) {
const { data: saveState } = useQuery(
// Query should be initialized
api.teachers.getSave.queryOptions({
input: {
teacherId,
},
}),
);

return <div>SSR initialized save state: {JSON.stringify(saveState)}</div>;
}
If anyone has any suggestions on what to do here, I'd greatly appreciate it!
7 Replies
deep-jade
deep-jade2mo ago
TanStack Query Integration | TanStack Router Docs
[!IMPORTANT] This integration automates SSR dehydration/hydration and streaming between TanStack Router and TanStack Query. If you haven't read the standard guide, start there. What you get Automatic...
rare-sapphire
rare-sapphireOP2mo ago
Yes I am. The functionality works for the teacher query at the top of the loader. Which approach to initializing getSave query would you recommend? ensureData with initialData from teacher query or a queryFn that returns the initial data?
deep-jade
deep-jade2mo ago
i was just wondering why you had that hydration boundary shouldnt be necessary
rare-sapphire
rare-sapphireOP2mo ago
Hmm, so setting the query data manually should be enough?
deep-jade
deep-jade2mo ago
i think so if not, a complete minimal reproducer project is needed to dig into
rare-sapphire
rare-sapphireOP2mo ago
Alright, there was no issue afterall. As usual, an error on my part.
deep-jade
deep-jade2mo ago
so is it working now?

Did you find this page helpful?