Ragpud
Ragpud•12mo ago

Ents + Server components

Hello 👋 I'm using convex with NextJS and the preloadQuery and fetchQuery methods are working great for me. The only thing I can see getting in my way a the moment is the Ents types. In the docs it says you can specify a prop from a server component with:
preloadedTasks: Preloaded<typeof api.tasks.list>;
preloadedTasks: Preloaded<typeof api.tasks.list>;
However when using Ents the return type of queries doesn't equal Preloaded<typeof api.tasks.list>. I can't see anything in the Ents docs about this. So what I'm asking is: is what I'm trying to do not possible, not been tried before yet or just not documented yet? I reckon the answer lies in just a fancy typescript type, although unfortunately I'm not good enough with typescript yet to figure it out.
4 Replies
Michal Srb
Michal Srb•12mo ago
Hey @Ragpud, this should work fine. Mind sharing more on what you've tried: Your code snippets, and the error you're getting?
Ragpud
RagpudOP•12mo ago
Hi Michael, certainly. Here's my query:
export const getAll = zQuery({
args: { user: zid("users") },
handler: async (ctx: QueryCtx, { user }) => {
const tasks = await ctx
.table("users")
.getX(user)
.edge("tasks");

return tasks;
},
});
export const getAll = zQuery({
args: { user: zid("users") },
handler: async (ctx: QueryCtx, { user }) => {
const tasks = await ctx
.table("users")
.getX(user)
.edge("tasks");

return tasks;
},
});
I forgot to add I'm using the convex zod helpers, so here's the zQuery function for context:
export const zQuery = zCustomQuery(
query,
customCtx(async (ctx) => {
return {
table: entsTableFactory(ctx, entDefinitions),
db: undefined,
};
})
);
export const zQuery = zCustomQuery(
query,
customCtx(async (ctx) => {
return {
table: entsTableFactory(ctx, entDefinitions),
db: undefined,
};
})
);
I'm calling the query like so in a react component:
const preloadedTasks = await preloadQuery(api.tasks.getAll, {
audioGuideId: audioGuideId,
});
return <Tasks tasks={preloadedTasks} />
const preloadedTasks = await preloadQuery(api.tasks.getAll, {
audioGuideId: audioGuideId,
});
return <Tasks tasks={preloadedTasks} />
and passing it into a component below as documented, to be used with usePreloadedQuery. The problem occurs when specifying the props in the component that consumes the preloaded query:
const Tasks = ({preloadedTasks}: {preloadedTasks: Preloaded<typeof api.tasks.getAll>)
const Tasks = ({preloadedTasks}: {preloadedTasks: Preloaded<typeof api.tasks.getAll>)
What I'm passing into Tasks doesn't match what's expected for some reason, I think it's because the Preloaded helper doesn't expect an Ents table?
Michal Srb
Michal Srb•12mo ago
Can you show the typescript error? (the context here (db/table) is irrelevant, only the return type of the function matters)
Ragpud
RagpudOP•12mo ago
Sorry my bad, in typing out the response I realised I made a typo along the way. I spent a long time figuring out how to make a custom preloadQuery function the same way I've mad a custom query and mutation for Ents, my apologies apologies!

Did you find this page helpful?