X
Xata6mo 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
kostas6mo 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
SmokeyFroOP6mo 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
kostas6mo 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
SmokeyFroOP6mo ago
It is there. without the export part
kostas
kostas6mo 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
SmokeyFroOP6mo 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
kostas6mo 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
SmokeyFroOP6mo 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
kostas6mo 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
SmokeyFroOP6mo 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
kostas6mo ago
Which API call is the one generating the error currently?
SmokeyFro
SmokeyFroOP6mo 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
kostas6mo 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
SmokeyFroOP6mo 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
kostas6mo 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;
}
SmokeyFro
SmokeyFroOP6mo ago
ah, thanks for checking! do you run into the same issue using the original post repo? might be that I messed something up while attempting to implement it.
kostas
kostas6mo ago
Basically I am switching the filter to work against the id field here, which seems to make things work This code is identical to the original repo, so I think these filters need fixing (but I'd need to check with the author if that follows the correct logic)
SmokeyFro
SmokeyFroOP6mo ago
I updated the function, but now get a 404 when i land on the /api/sign/up or /on endpoints.
kostas
kostas6mo ago
I believe the correct endpoint is localhost:3000/signup etc the /api/sign/up is internal only
SmokeyFro
SmokeyFroOP6mo ago
sorry, i meant i signed up using /signup then get redirected to /api/sign/up. looking at the error log, it's saying the get request is 404, but it's been sent and received as a post. GET http://localhost:3000/api/sign/up [HTTP/1.1 404 Not Found 6ms] the signup form is set to: <form method="post" action="/api/sign/up"> and the endpoint is set to: export async function POST({ request, redirect, cookies }: APIContext): Promise<Response> { not sure why its being interpreted as a get request.
kostas
kostas6mo ago
With just the change we discussed, the signin and signup flow work well for me. Make sure you're not being bitten by browser cache?
SmokeyFro
SmokeyFroOP6mo ago
ah cool, let me clear my cache quick and see if that helps. i needed to update the getUserFromSessionId function assigning to the session_id to id and now it works. I'm not taken to the login page like you were in the video, but rather redirected to the / and now showing as logged in 😄 private async getUserFromSessionId(session_id: string): Promise<DatabaseUser | null> { const theSession = await this.controller.db.session.filter({ id: session_id }).getFirst(); thank you for all your help. 🙏
kostas
kostas6mo ago
Sounds like there is some progress! I apologize for the issues you encountered with the code, we'll review and make adjustments to make sure things work smooth
SmokeyFro
SmokeyFroOP6mo ago
nah, it's all good. it's the nature of coding. glad we were able to determine the root cause. i'm absolutely loving xata, so it's not a biggie if there are some small teething issues. i have a better understanding of the code after the debug sesh. one last question. is it possible to setup a new schema via code? like a template preset i could use as a theme author to help setup a themes back-end - kinda like in the xata.ts, but in reverse? like if i were to build a theme that uses xata as the backend, to have it automatically setup the scheme based on a conf file or script. i've been building a commenting engine using astro db and was thinking it would be cool to support multiple providers (astro db, xata, etc) and it would be cool to automate the setup process - same with xata based themes.
kostas
kostas6mo ago
Certainly, there are some guidelines here: https://xata.io/docs/getting-started/installation#committing-files-to-your-repository see the section after "When creating templates or examples for public use and cloning..." Basically you can export the schema that your project intends to use (with "xata schema dump"), commit it to your repo and add instructions for users to import it to their database. This way they can easily setup their database to match your intended schema.
SmokeyFro
SmokeyFroOP6mo ago
awesome 😄 i'll defos give that a go. :xatafly:
Want results from more Discord servers?
Add your server