How to fetch based on session? Getting 'session possibly null' with useQuery...

Let's say I am getting the session from the useSession hook and with ReactQuery I am setting the enabled status if the user is authenticated like so:
const { data: userProjects } = api.project.getByUserId.useQuery(
{
userId: session.user.id,
},
{
enabled: status === "authenticated",
}
);
const { data: userProjects } = api.project.getByUserId.useQuery(
{
userId: session.user.id,
},
{
enabled: status === "authenticated",
}
);
If I keep my code like this I get the error mentioned in the title, so how can I tell TypeScript that's safe doing so because we will run the query only if the user is authenticated? Instead, if I change it to session?.user.id I get the "Overload matches error" ending with Type 'undefined' is not assignable to type 'string'. Does anyone have an advice?
8 Replies
cupofcrypto
cupofcryptoā€¢2y ago
For the current user I avoided the issue using session right in tRPC, but what should I do if I want to check the project of a different one?
// My procedures
getByUserId: protectedProcedure
.input(z.object({ userId: z.string() }))
.query(({ ctx, input }) => {
return ctx.prisma.project.findMany({
where: {
userId: input.userId,
},
});
}),
getByCurrentUser: protectedProcedure.query(({ ctx }) => {
return ctx.prisma.project.findMany({
where: {
userId: ctx.session.user.id,
},
});
}),
// My procedures
getByUserId: protectedProcedure
.input(z.object({ userId: z.string() }))
.query(({ ctx, input }) => {
return ctx.prisma.project.findMany({
where: {
userId: input.userId,
},
});
}),
getByCurrentUser: protectedProcedure.query(({ ctx }) => {
return ctx.prisma.project.findMany({
where: {
userId: ctx.session.user.id,
},
});
}),
Keef
Keefā€¢2y ago
Usually I wrap the useSession hook with one that handles unauthenticated (redirect to log in) and returns a asserted blob. There might be a better way but I find this gets the job done since the client side is where the session has the typedef of Session | undefined. On the server you are using protected procedure which basically does what the client side hook i propose does
const { data: userProjects } = api.project.getByUserId.useQuery(
{
userId: session.user.id as String,
},
{
enabled: status === "authenticated",
}
);
const { data: userProjects } = api.project.getByUserId.useQuery(
{
userId: session.user.id as String,
},
{
enabled: status === "authenticated",
}
);
This is the lazy way to fix it but you will have to do this anywhere you want to use something from your session blob Its safe to "override" because it will never run in the case of no auth
barry
barryā€¢2y ago
enabled: !!session.user.id Why make it more complicated
Keef
Keefā€¢2y ago
I don't think ts gets the hint that it'll be there so you still have to do an assertion even with that Atleast i remember that being the case when I had to deal w this back then
cupofcrypto
cupofcryptoā€¢2y ago
Strange, it did not solve the issue like that. I have to keep the optional chaining in order for errors to go away
cupofcrypto
cupofcryptoā€¢2y ago
good point in making it simpler, but it does nothing specific to my issue
Keef
Keefā€¢2y ago
oh eslint u bastard šŸ˜  Mine isn't set up as strict/ not on the newest versions which might be why its not picked up You'll need to narrow the type first before using it
cupofcrypto
cupofcryptoā€¢2y ago
tbh for the time being this session?.user.id as string will make the trick. Right now I am not that expert with TypeScript and my focus is more on closing this app with some standard features. Pretty sure that with time I'll be able to figure out what's going on and why if I use session?.user.id I get the No overload match this call on userId thanks for the help anyway šŸ˜‰
Want results from more Discord servers?
Add your server