epsilon42
epsilon42
Explore posts from servers
TTCTheo's Typesafe Cult
Created by epsilon42 on 7/27/2024 in #questions
useQuery in NextJS app router client components
Thanks @cje. Thought it would be something silly like this I was doing!
4 replies
DTDrizzle Team
Created by epsilon42 on 5/15/2024 in #help
.unique() doesn't seem to work
Thanks @Mykhailo I was on the v0.21.1. Update to v0.21.2 fixed it.
4 replies
TTCTheo's Typesafe Cult
Created by epsilon42 on 5/13/2024 in #questions
How to prevent multiple DB calls in this situation
Thanks @TerjaN I didn't know about this. I initially thought your recommendation wasn't work as I was still seeing 2 of the same DB query logged, but it was due to getUser being called differently:
await getUser({ ensureSignedIn: true });
vs
await getUser();
await getUser({ ensureSignedIn: true });
vs
await getUser();
Split the function in two and cached the DB calling part and now it only does one DB query:

const getDbUser = cache(async (authUserId?: string) => {
let dbUser;
if (authUserId) {
dbUser = await db.query.users.findFirst({
where: (model, { eq }) => eq(model.authProviderId, authUserId),
});
if (!dbUser) {
dbUser = await db
.insert(users)
.values({
authProviderId: authUserId,
})
.returning();
}
}

return Array.isArray(dbUser) ? dbUser[0] : dbUser;
});

// Only use this getUser in /app/
export const getUser = async (options: Options = {}) => {
console.log("customGetUser");
const { ensureSignedIn } = options;
const authUser = ensureSignedIn
? await workOsGetUser({ ensureSignedIn: true })
: await workOsGetUser();

const dbUser = await getDbUser(authUser.user?.id);

return {
user: authUser.user,
role: authUser.role,
dbUser,
hasRegistered: authUser.user && dbUser,
hasUsername: dbUser?.username,
};
};

const getDbUser = cache(async (authUserId?: string) => {
let dbUser;
if (authUserId) {
dbUser = await db.query.users.findFirst({
where: (model, { eq }) => eq(model.authProviderId, authUserId),
});
if (!dbUser) {
dbUser = await db
.insert(users)
.values({
authProviderId: authUserId,
})
.returning();
}
}

return Array.isArray(dbUser) ? dbUser[0] : dbUser;
});

// Only use this getUser in /app/
export const getUser = async (options: Options = {}) => {
console.log("customGetUser");
const { ensureSignedIn } = options;
const authUser = ensureSignedIn
? await workOsGetUser({ ensureSignedIn: true })
: await workOsGetUser();

const dbUser = await getDbUser(authUser.user?.id);

return {
user: authUser.user,
role: authUser.role,
dbUser,
hasRegistered: authUser.user && dbUser,
hasUsername: dbUser?.username,
};
};
8 replies
TTCTheo's Typesafe Cult
Created by epsilon42 on 5/13/2024 in #questions
How to prevent multiple DB calls in this situation
How should I structure it so that it only makes one DB call per page, or only when initial application loads? The AuthKit getUser function alone doesn't require any extra DB calls because it gets the user information from the cookie, but in my application I would like to get some extra info from the Users table in the DB.
8 replies
TTCTheo's Typesafe Cult
Created by epsilon42 on 5/13/2024 in #questions
How to prevent multiple DB calls in this situation
I can use this in pages and components like so:
// app/private/page.tsx
import { SignInButton } from "../_components/sign-in-button";
import { getUser } from "../_lib/getUser";

export default async function Private() {
const { hasRegistered, hasUsername, dbUser } = await getUser({
ensureSignedIn: true,
});

if (hasUsername) {
return (
<div>
<h1>Private</h1>
<p>Welcome back, {dbUser?.username}</p>

<SignInButton />
</div>
);
}

if (hasRegistered) {
return (
<div>
<h1>Private</h1>
<p>Welcome, you must first setup a username</p>

<SignInButton />
</div>
);
}

// console.log({ user });
return (
<div>
<h1>Private</h1>
<p>Unauthorized</p>
<p>Shouldnt see this as it should redirect before rendering</p>
</div>
);
}
// app/private/page.tsx
import { SignInButton } from "../_components/sign-in-button";
import { getUser } from "../_lib/getUser";

export default async function Private() {
const { hasRegistered, hasUsername, dbUser } = await getUser({
ensureSignedIn: true,
});

if (hasUsername) {
return (
<div>
<h1>Private</h1>
<p>Welcome back, {dbUser?.username}</p>

<SignInButton />
</div>
);
}

if (hasRegistered) {
return (
<div>
<h1>Private</h1>
<p>Welcome, you must first setup a username</p>

<SignInButton />
</div>
);
}

// console.log({ user });
return (
<div>
<h1>Private</h1>
<p>Unauthorized</p>
<p>Shouldnt see this as it should redirect before rendering</p>
</div>
);
}
// app/_components/sign-in-button.tsx
import { getSignInUrl, signOut } from "@workos-inc/authkit-nextjs";
import { getUser } from "../_lib/getUser";

export async function SignInButton() {
const { hasRegistered } = await getUser();
const authorizationUrl = await getSignInUrl();

if (hasRegistered) {
return (
<div>
<form
action={async () => {
"use server";
await signOut();
}}
>
<button>Sign Out</button>
</form>
</div>
);
}

return (
<button>
<a href={authorizationUrl}>Sign In</a>
</button>
);
}
// app/_components/sign-in-button.tsx
import { getSignInUrl, signOut } from "@workos-inc/authkit-nextjs";
import { getUser } from "../_lib/getUser";

export async function SignInButton() {
const { hasRegistered } = await getUser();
const authorizationUrl = await getSignInUrl();

if (hasRegistered) {
return (
<div>
<form
action={async () => {
"use server";
await signOut();
}}
>
<button>Sign Out</button>
</form>
</div>
);
}

return (
<button>
<a href={authorizationUrl}>Sign In</a>
</button>
);
}
This appears to work fine on the surface, but the problem I am facing is that if I have a page with many components that use getUser then I end up making multiple DB calls when essentially I should only need to make one DB call on page load:
// Server log
customGetUser
customGetUser <--- See this runs twice due to getUser being called in app/private/page.tsx and app/_components/sign-in-button.tsx
GET /private 200 in 28ms
// Server log
customGetUser
customGetUser <--- See this runs twice due to getUser being called in app/private/page.tsx and app/_components/sign-in-button.tsx
GET /private 200 in 28ms
8 replies
TTCTheo's Typesafe Cult
Created by RobCipolla on 4/9/2024 in #questions
Clerk and tRPC "protectedProcedures" on the server.
Not sure if this is what you're after but Theo's T3 stack tutorial uses Clerk for privateProcedure's: https://www.youtube.com/watch?v=YkOSUVzOAA4 Here's how he does it: https://github.com/t3dotgg/chirp/blob/main/src/server/api/trpc.ts
7 replies
TTCTheo's Typesafe Cult
Created by maskmonarch on 7/26/2023 in #questions
React not updating the attribute for an HTML element
is the text always the same if your viewport is > 1200 and you refresh vs < 1200 and refresh? or does it show the correct text?
25 replies
TTCTheo's Typesafe Cult
Created by maskmonarch on 7/26/2023 in #questions
React not updating the attribute for an HTML element
Ah sorry i missed the part where is only happening in prod. How odd.
25 replies
TTCTheo's Typesafe Cult
Created by maskmonarch on 7/26/2023 in #questions
React not updating the attribute for an HTML element
Can you show us some code
25 replies
TTCTheo's Typesafe Cult
Created by thevalorised on 7/19/2023 in #questions
How to wait for useState to finish before setting useRef value?
Are these supposed to be two separate forms, or two inputs in a single form? Not understanding the whole context/problem but wanted to add that you can also add a ref to the form tag, and name your inputs and in your onSubmit you can use it like: formRef.current.subcategory.value formRef.current.reset()
11 replies
TTCTheo's Typesafe Cult
Created by minotaurr on 7/16/2023 in #questions
I have been stuck on this Type error: Cannot find name 'TRPCError'. Did you mean 'RTCError'?
4 replies
TTCTheo's Typesafe Cult
Created by epsilon42 on 6/9/2023 in #questions
Add token requirement to public TRPC endpoint to add to DB (create-t3-app)
Is the reason you're suggesting abstracting it to another function just in the case that I want to share the same logic/functionality within tRPC? In this particular case I don't see the functionality needing to be called from within the app, only triggered externally. Does this mean I would only need to have the logic in pages/api/my-externally-called-function.ts ?
5 replies
TTCTheo's Typesafe Cult
Created by epsilon42 on 6/9/2023 in #questions
Add token requirement to public TRPC endpoint to add to DB (create-t3-app)
(Post continued from above) I then realised that for all I've seen so far with TRPC, the data is all within the query string, not in the body of the request. So I guess I could change the request and change it so that it's something like /api/trpc/example.create?token=SECRETSAUCE, (probably looks a bit different to this - haven't tried this yet) but I have read that this is bad practice because it exposes the token in logs etc. So my first question is: - Is it okay to add token in query string, or is there a way of extracting the data from the body of the request to validate the token sent in the body? Some other questions: - Should I be using protectedProcedure somehow or is publicProcedure the right one to use here? - Should I be avoiding TRPC altogether (the example code below seems to work when POSTing a token in the body but not sure how to add something to DB)?
// Creating a non-TRPC endpoint like below works, but not sure how to add to DB
// src/pages/api/cron-test.ts
import type { NextApiRequest, NextApiResponse } from "next";

function validateToken(token: string): boolean {
return token === "SECRETSAUCE";
}

export default function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method === "POST") {
const { token } = req.body as { token: string };

if (!token || !validateToken(token)) {
res.status(401).json({ message: "Invalid or missing token" });
return;
}

// ... Add to DB here
res.status(200).json({ message: "POST request handled with token" });
} else {
res.status(405).json({ message: "Method Not Allowed" });
}
}
// Creating a non-TRPC endpoint like below works, but not sure how to add to DB
// src/pages/api/cron-test.ts
import type { NextApiRequest, NextApiResponse } from "next";

function validateToken(token: string): boolean {
return token === "SECRETSAUCE";
}

export default function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method === "POST") {
const { token } = req.body as { token: string };

if (!token || !validateToken(token)) {
res.status(401).json({ message: "Invalid or missing token" });
return;
}

// ... Add to DB here
res.status(200).json({ message: "POST request handled with token" });
} else {
res.status(405).json({ message: "Method Not Allowed" });
}
}
There's a very real possibility that I'm approaching this the wrong way so please let me know if I should be doing something differently. I'm coming from a frontend background and quite new to backend/API stuff.
5 replies
TTCTheo's Typesafe Cult
Created by ruta123 on 6/3/2023 in #questions
looking for some tutorials
Haven't used rails, but I've heard that redwoodjs is a similar experience. In terms of create-t3-app i found these videos useful: theo's (twitter clone, uses clerk for auth, steps you through all the way to deployment): https://www.youtube.com/watch?v=YkOSUVzOAA4 Another one I found useful (todo app, nextauth - magic link auth): https://www.youtube.com/watch?v=S3k82XXCrBo Pretty similar to theo's (twitter clone) but uses discord auth: https://www.youtube.com/watch?v=jqVm5_G1ZEE
10 replies
TTCTheo's Typesafe Cult
Created by cupofcrypto on 5/29/2023 in #questions
Stuck with a TS error for `Object.keys` 😞
25 replies
TTCTheo's Typesafe Cult
Created by epsilon42 on 5/29/2023 in #questions
runtimeEnv property in env.mjs in create-t3-app
ah ok... i guess i'm not really sure on how nodemailer is able to access the variables in the .env though? what sets it apart?
6 replies
TTCTheo's Typesafe Cult
Created by epsilon42 on 5/29/2023 in #questions
runtimeEnv property in env.mjs in create-t3-app
I have these ones:
DATABASE_URL: process.env.DATABASE_URL,
NODE_ENV: process.env.NODE_ENV,
NEXTAUTH_SECRET: process.env.NEXTAUTH_SECRET,
NEXTAUTH_URL: process.env.NEXTAUTH_URL,
DATABASE_URL: process.env.DATABASE_URL,
NODE_ENV: process.env.NODE_ENV,
NEXTAUTH_SECRET: process.env.NEXTAUTH_SECRET,
NEXTAUTH_URL: process.env.NEXTAUTH_URL,
But I also added nodemailer and specified EMAIL_SERVER and EMAIL_FROM in the .env and it seems to be working fine.
6 replies
TTCTheo's Typesafe Cult
Created by cupofcrypto on 5/29/2023 in #questions
Stuck with a TS error for `Object.keys` 😞
its a bit hard to tell, but i think it's probably something to do with the response. when you hover over the api response what type does it give you? doesn't seem right that you need to be doing this undefined check.
25 replies
TTCTheo's Typesafe Cult
Created by cupofcrypto on 5/29/2023 in #questions
Stuck with a TS error for `Object.keys` 😞
so is there still a problem youre having
25 replies