X
Xata2mo ago
SmokeyFro

Cannot destructure property 'id' of 'raw' as it is null (following the Astro tut)

Howdy folks. I'm pretty new to Xata and have to say so far it's pretty dang awesome. I'm still figuring things out and have been going through the Astro, Xata, Stripe & Lucia tut (sans the stripe part). The user registration and session parts are working, but I'm getting the following error when signing up as a new user: "Cannot destructure property 'id' of 'raw' as it is null.". Checking the code I see its referring to line 22 of the transformIntoDatabaseSession function in the lucia/xata.ts:
function transformIntoDatabaseSession(raw: SessionSchema): DatabaseSession {
const { id, user_id: userId, expires_at: expiresAt, ...attributes } = raw;
return {
id,
userId,
expiresAt,
attributes
};
}
function transformIntoDatabaseSession(raw: SessionSchema): DatabaseSession {
const { id, user_id: userId, expires_at: expiresAt, ...attributes } = raw;
return {
id,
userId,
expiresAt,
attributes
};
}
Looking in the db and I can see the id is there, so not sure how to get around the error. Anyone have any ideas of what I'm missing?
26 Replies
kostas
kostas2mo ago
Hi, I suppose you created a database in Xata and set up the schema to match the one used by this repo, right? https://github.com/rishi-raj-jain/protected-and-paid-stripe-xata/blob/master/src/xata.ts#L9 After making changes in the UI, you need to run "xata codegen" locally in the project, which will refresh the src/xata.ts file with the latest state of your Xata database Since transformIntoDatabaseSession is called by getSession which retrieves a record based on matching session_id, and there is no check for empty response there, it sounds like that getFirst does not find any results which then results to the error you get https://github.com/rishi-raj-jain/protected-and-paid-stripe-xata/blob/master/src/lucia/xata.ts#L75 I just gave the github repo a try and the /api/sign/up api worked well creating a new user in Xata. If you're encountering any issues it might help to place your code (if you've made changes) in a GH repo so we can have a look
SmokeyFro
SmokeyFro2mo ago
Hi Kostas 🙂 Thank you for taking the time to respond. I created the database before starting to implement the auth stuff and did the initial codegen. I made a couple of changes to the db structure to better match the tut, then updated the xata.ts manually to reflect the changes. Let me try running the xata codegen again. I re-ran the xata codegen, but now getting 12:58:55 [watch] src/lucia/xata.ts 12:58:55 [ERROR] Option apiKey is required. I took a look in the xata.ts that is in the lucia folder, but can't really see where to add the apiKey env.
kostas
kostas2mo ago
That would be the xata api key which is expected as an env var: export XATA_API_KEY="xau_yourkey" Or it should be in the .env file and loaded by Astro
SmokeyFro
SmokeyFro2mo ago
It is there. without the export part
kostas
kostas2mo ago
yeah in .env that is normal (I mean it doesn't need the export part there) Weird, as Astro should load it from there. Are you running it locally or on Vercel? If locally, does anything change if you export the variable on your terminal before running the project?
SmokeyFro
SmokeyFro2mo ago
I set it via the main xata.ts, where the xata instance is defined. that's cleared the apiToken issue, but now back to the original error. I'm running locally in hybrid mode with the cloudflare adapter.
kostas
kostas2mo ago
Just for clarity, getXataClient starts a Xata client instance which "defaults" to reading the api key from .env or env variables. If for some reason that isn't working, the recommended approach is to replace getXataClient with XataClient with the apiKey variable explicitly passed to it like here: https://xata.io/docs/sdk/typescript/overview#manually-passing-the-apikey Seems we have some extra info in the generic Astro guide here which may be useful: https://xata.io/docs/getting-started/astro#create-a-new-database see the additions to src/env.d.ts That said, is there any user created in your "user" table in Xata?
SmokeyFro
SmokeyFro2mo ago
ah, good to know. thanks for clarifying. I reverted the main xata.ts, then updated the lucia/xata.ts to use the suggested method. yeah, i used the official tut as a reference.
kostas
kostas2mo ago
The main xata.ts should always be generated by "xata codegen" (as the Xata CLI creates that and may rewrite it in the future so any of your changes can get lost)
SmokeyFro
SmokeyFro2mo ago
for the users table, yeah i was able to register from the astro site and it created the user and session, so that part is working. noted 🙂
kostas
kostas2mo ago
Which API call is the one generating the error currently?
SmokeyFro
SmokeyFro2mo ago
the error is shown after registering (/pages/signup), when i'm redirected to http://localhost:3000/api/sign/up. i just tested it again and it created the user, session and set the session cookie, but again showing the original error after being redirected to the endpoint. I haven't created a repo yet, but he is the full code so far.
kostas
kostas2mo ago
So you visit localhost:3000/signup , fill in the fields email/passwd and continue It creates the user in Xata but it redirects you back to /api/sign/up? That's weird because the redirect is to the landing page , there's no redurect to /api/sign/up again: https://github.com/rishi-raj-jain/protected-and-paid-stripe-xata/blob/master/src/pages/api/sign/up.ts#L26
SmokeyFro
SmokeyFro2mo ago
i guess maybe it's because the signup form is posting to that endpoint? <form method="post" action="/api/sign/up"> Seems like it's getting stuck on the error before redirecting to / i tested the sign in and it gives the same error. I then checked the sessions table and a new entry was added, but none of the entries have a session_id. Could that be causing the issue?
kostas
kostas2mo ago
I see, I tried running it locally and reproduced the issue. It's definitely because it can't get a matching session id which is an unhandled case. Adding a conditional avoids the issue:
private async getSession(session_id: string): Promise<DatabaseSession | null> {
const records = await this.controller.db.session.filter({ session_id }).getFirst();
if (records) {
return transformIntoDatabaseSession(records);
}
return null;
}
private async getSession(session_id: string): Promise<DatabaseSession | null> {
const records = await this.controller.db.session.filter({ session_id }).getFirst();
if (records) {
return transformIntoDatabaseSession(records);
}
return null;
}
But this doesn't fix the workflow however, the redirects don't work beyond that. When creating records in the session table it is using the id column to store session ids (the session_id column is empty). I'm not sure if the blog post was meant to use session_id instead of id. Maybe the blog author knows more? @Rishi Raj Jain Try:
private async getSession(session_id: string): Promise<DatabaseSession | null> {
const records = await this.controller.db.session.filter({ id: session_id }).getFirst();
if (records) {
return transformIntoDatabaseSession(records);
}
return null;
}
private async getSession(session_id: string): Promise<DatabaseSession | null> {
const records = await this.controller.db.session.filter({ id: session_id }).getFirst();
if (records) {
return transformIntoDatabaseSession(records);
}
return null;
}
Want results from more Discord servers?
Add your server