Luc Ledo
Luc Ledo
Explore posts from servers
TTCTheo's Typesafe Cult
Created by Luc Ledo on 10/29/2024 in #questions
Weird tech stack from coding assignment
I just got a coding assignment that ask me to use Next.js with Fastify (backend) and tRPC. As I understand it, tRPC uses typescript to connect the frontend and the backend. I've used tRPC in Next.js as the frontend and backend. But how exactly does tRPC work when the frontend and backend are separated? Is my understanding of tRPC wrong? Wouldn't fontend and backend need to be in the repository for tRPC & typescript to work?
14 replies
TTCTheo's Typesafe Cult
Created by Luc Ledo on 10/21/2024 in #questions
Need a free cursor pagination API for testing
Need something like https://jsonplaceholder.typicode.com/ but supports cursor pagination. Anything like that exist?
3 replies
TTCTheo's Typesafe Cult
Created by Luc Ledo on 1/30/2024 in #questions
Best way to get a react component's raw code?
Is it possible to get a component's raw code? For example.
function Post() {
return (
<div>post1</div>
)
}
function Post() {
return (
<div>post1</div>
)
}
then something like this
<code>{getRawCode(Post)}</code>
<code>{getRawCode(Post)}</code>
Basically, I want something like this: https://ui.shadcn.com/docs/components/accordion, where I can see the preview of the component and the raw code. Technically, I can just copy/paste the component's code into the <code> element but I want to have a single source of truth. And I did try looking at shadcn/ui repo but I did not understand how it worked at all.
13 replies
TTCTheo's Typesafe Cult
Created by Luc Ledo on 11/8/2023 in #questions
Passing in Form as prop in Shadcn/ui?
Basically I move FormField to another component and I need to pass in Form a props, the way I'm currently doing doesn't give auto-complete because of UseFormReturn<any>.
export default function FormComponent() {
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
folderID: 0,
},
})
return (
<Form>
<FolderIdFormField form={form} />
</Form>
}

export function FolderIdFormField({
form
}: {
form: UseFormReturn<any>;
}) {
...
return (
<FormField
control={form.control}
name='folderID'
render={({ field }) => (
...
)}
/>
);
}
export default function FormComponent() {
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
folderID: 0,
},
})
return (
<Form>
<FolderIdFormField form={form} />
</Form>
}

export function FolderIdFormField({
form
}: {
form: UseFormReturn<any>;
}) {
...
return (
<FormField
control={form.control}
name='folderID'
render={({ field }) => (
...
)}
/>
);
}
1 replies
TTCTheo's Typesafe Cult
Created by Luc Ledo on 10/13/2023 in #questions
Is my backend team right?🤔
So I'm working on an AI image gen app and I proposed a full text search feature that would allow users to search all their generated images based on the prompt. The problem is our image collection is over 1 billion rows (mongodb btw). They pushed back and said they tried this in the past and it was not performant because the collection/table is too big and it would sometimes take up to 8 seconds. Now I believe it's probably because they were doing full text search on the full 1 billion+ table/collection, but if we query by first filtering it down based on userID first then perform the full text search on that much smaller set it would be performant right? I only know SQL database so I'm not sure but it wouldn't be similar for mongodb too? And if you know more performant way to do this, please let me know🙏
11 replies
TTCTheo's Typesafe Cult
Created by Luc Ledo on 10/6/2023 in #questions
Uploadthing: Is there way to view all uploaded items?
Haven't started using it yet just to be clear but don't see any info about how to view all the uploaded items. If I lose the item url how will I interact with it from then on? Can I view all my uploaded item on amazon s3 or something like a prisma studio?
7 replies
TTCTheo's Typesafe Cult
Created by Luc Ledo on 8/24/2023 in #questions
Can't get OG to show
https://github.com/Apestein/nextflix/blob/main/src/app/layout.tsx
const siteConfig = {
title: "Netflix Clone",
description:
"Open source project using bleeding-edge stack. Drizzle ORM + Neon postgres + Clerk auth + Shadcn/ui + everything new in Next.js 13 (server components, server actions, streaming ui, parallel routes, intercepting routes).",
url: "https://nextflix-blush.vercel.app/",
og: "https://nextflix-blush.vercel.app/og.png",
siteName: "Nextflix",
}
export const metadata = {
title: siteConfig.title,
description: siteConfig.description,
openGraph: {
images: [siteConfig.og],
title: siteConfig.title,
description: siteConfig.description,
url: siteConfig.url,
siteName: siteConfig.siteName,
locale: "en_US",
type: "website",
},
twitter: {
card: "summary_large_image",
images: [siteConfig.og],
title: siteConfig.title,
description: siteConfig.description,
},
}
const siteConfig = {
title: "Netflix Clone",
description:
"Open source project using bleeding-edge stack. Drizzle ORM + Neon postgres + Clerk auth + Shadcn/ui + everything new in Next.js 13 (server components, server actions, streaming ui, parallel routes, intercepting routes).",
url: "https://nextflix-blush.vercel.app/",
og: "https://nextflix-blush.vercel.app/og.png",
siteName: "Nextflix",
}
export const metadata = {
title: siteConfig.title,
description: siteConfig.description,
openGraph: {
images: [siteConfig.og],
title: siteConfig.title,
description: siteConfig.description,
url: siteConfig.url,
siteName: siteConfig.siteName,
locale: "en_US",
type: "website",
},
twitter: {
card: "summary_large_image",
images: [siteConfig.og],
title: siteConfig.title,
description: siteConfig.description,
},
}
site: https://nextflix-blush.vercel.app/ I can't get og to show on Discord and Twitter. I'm following this repo example exactly, I don't understand why it won't show. https://github.com/Nutlope/roomGPT
11 replies
TTCTheo's Typesafe Cult
Created by Luc Ledo on 8/16/2023 in #questions
SQL Querying Best Practices?
Just want to discuss query best practices. I using drizzle here but I'm just talking about SQL in general.
const userAccount = await db.query.accounts.findFirst({
where: eq(accounts.id, userId),
with: {
activeProfile: {
with: {
savedShows: {
where: eq(myShows.id, input.id),
limit: 1, // Does using limit matter here? It should speed up query right?
},
},
},
},
})
const userAccount = await db.query.accounts.findFirst({
where: eq(accounts.id, userId),
with: {
activeProfile: {
with: {
savedShows: {
where: eq(myShows.id, input.id),
limit: 1, // Does using limit matter here? It should speed up query right?
},
},
},
},
})
And since I only need the nested relations. Relevant Drizzle docs: https://orm.drizzle.team/docs/rqb#partial-fields-select
const userAccount = await db.query.accounts.findFirst({
columns: {}, // Would this matter? Does it speed up queries? It would transfer less data but is that all?
where: eq(accounts.id, userId),
with: {
activeProfile: {
with: {
savedShows: {
where: eq(myShows.id, input.id),
limit: 1,
},
},
},
},
})
const userAccount = await db.query.accounts.findFirst({
columns: {}, // Would this matter? Does it speed up queries? It would transfer less data but is that all?
where: eq(accounts.id, userId),
with: {
activeProfile: {
with: {
savedShows: {
where: eq(myShows.id, input.id),
limit: 1,
},
},
},
},
})
Also, this is a query to check if a show is saved to a profile. It just returns true or false. I feel there is probably a better way to query this but I'm not sure how. Maybe a way using count?
1 replies
DTDrizzle Team
Created by Luc Ledo on 8/16/2023 in #help
Querying Best Practices?
Just want to discuss query best practices.
const userAccount = await db.query.accounts.findFirst({
where: eq(accounts.id, userId),
with: {
activeProfile: {
with: {
savedShows: {
where: eq(myShows.id, input.id),
limit: 1, // Does using limit matter here? It should speed up query right?
},
},
},
},
})
const userAccount = await db.query.accounts.findFirst({
where: eq(accounts.id, userId),
with: {
activeProfile: {
with: {
savedShows: {
where: eq(myShows.id, input.id),
limit: 1, // Does using limit matter here? It should speed up query right?
},
},
},
},
})
And since I only need the nested relations
const userAccount = await db.query.accounts.findFirst({
columns: {}, // Would this matter? Does it speed up queries? It would transfer less data but is that all?
where: eq(accounts.id, userId),
with: {
activeProfile: {
with: {
savedShows: {
where: eq(myShows.id, input.id),
limit: 1,
},
},
},
},
})
const userAccount = await db.query.accounts.findFirst({
columns: {}, // Would this matter? Does it speed up queries? It would transfer less data but is that all?
where: eq(accounts.id, userId),
with: {
activeProfile: {
with: {
savedShows: {
where: eq(myShows.id, input.id),
limit: 1,
},
},
},
},
})
8 replies
TTCTheo's Typesafe Cult
Created by Luc Ledo on 8/15/2023 in #questions
Suspense triggers weird bug
I have a component like this:
async function Foo() {
const { userId } = auth()
if (!userId) return
console.count()
const existingAccount = await getAccount(userId)
const account = existingAccount
? existingAccount
: await createAccountAndProfile() //this line should only get called the first time but it gets called twice
if (!account) throw new Error(ERR.db)
}
async function Foo() {
const { userId } = auth()
if (!userId) return
console.count()
const existingAccount = await getAccount(userId)
const account = existingAccount
? existingAccount
: await createAccountAndProfile() //this line should only get called the first time but it gets called twice
if (!account) throw new Error(ERR.db)
}
<Suspense fallback="loading">
<Foo/>
<Suspense/>
<Suspense fallback="loading">
<Foo/>
<Suspense/>
If I remove the suspense it works as normal.
1 replies
TTCTheo's Typesafe Cult
Created by Luc Ledo on 8/12/2023 in #questions
Take over login flow from Clerk?
Is there a way to take over login flow? I'm using webhook and problem is Clerk login users before they can be created in database through webhooks. I need a way to take over login flow, await for user to be created in the database, then redirect to main page.
1 replies
TTCTheo's Typesafe Cult
Created by Luc Ledo on 8/10/2023 in #questions
How to extract tuple from array of objects for Zod enums?
export const PLANS = [
{
id: "0",
name: "free",
price: 0,
description: "Free Video Stream",
},
{
id: "price_1Nd",
name: "basic",
price: 5,
description: "Basic Video Stream",
},
{
id: "price_1Nd",
name: "standard",
price: 10,
description: "Standard Video Stream",
},
{
id: "price_1Nd",
name: "premium",
price: 20,
description: "Premium Video Stream",
},
] as const

const planNames = PLANS.map((plan) => plan.name)
// ("free" | "basic" | "standard" | "premium")[] what I get
// ["free", "basic", "standard", "premium"] what I want
export const PLANS = [
{
id: "0",
name: "free",
price: 0,
description: "Free Video Stream",
},
{
id: "price_1Nd",
name: "basic",
price: 5,
description: "Basic Video Stream",
},
{
id: "price_1Nd",
name: "standard",
price: 10,
description: "Standard Video Stream",
},
{
id: "price_1Nd",
name: "premium",
price: 20,
description: "Premium Video Stream",
},
] as const

const planNames = PLANS.map((plan) => plan.name)
// ("free" | "basic" | "standard" | "premium")[] what I get
// ["free", "basic", "standard", "premium"] what I want
I need this for zod validation. Currently, I'm doing this way.
z.object({
stripeProductId: z.string(),
planName: z.enum(["free", "basic", "standard", "premium"]),
}),
z.object({
stripeProductId: z.string(),
planName: z.enum(["free", "basic", "standard", "premium"]),
}),
3 replies
TTCTheo's Typesafe Cult
Created by Luc Ledo on 8/8/2023 in #questions
revalidatePath invalidates all route cache
Is this a known bug? I see no one mention it yet but calling revalidatePath in a server actions invalidates all route cache not just the one specified.
1 replies
TTCTheo's Typesafe Cult
Created by Luc Ledo on 8/6/2023 in #questions
How to wait for state to update without useEffect?
Basically I have custom hook that looks like this:
const [data, setData] = useState<ResponseType | null>(null)
const [isLoading, setLoading] = useState(false)
const [isRunning, setRunning] = useState(false)
const [err, setErr] = useState<Error | null>(null)

const execute = useMemo(
() => async (input: z.infer<InputType>) => {
setRunning(true)
try {
const result = await actionRef.current(input)
setData(result)
setRunning(false)
} catch (e) {
console.log(e)
setErr(e as Error)
setRunning(false)
}
},
[],
)
return {execute, data, isLoading, isRunning, err}
const [data, setData] = useState<ResponseType | null>(null)
const [isLoading, setLoading] = useState(false)
const [isRunning, setRunning] = useState(false)
const [err, setErr] = useState<Error | null>(null)

const execute = useMemo(
() => async (input: z.infer<InputType>) => {
setRunning(true)
try {
const result = await actionRef.current(input)
setData(result)
setRunning(false)
} catch (e) {
console.log(e)
setErr(e as Error)
setRunning(false)
}
},
[],
)
return {execute, data, isLoading, isRunning, err}
Then I call it like this:
const {execute, data} = useFoo()
async function doAction() {
await execute({
id: id,
})
console.log(data) // doesn't work, return stale data instead of waiting for execute to finish updating state
}
const {execute, data} = useFoo()
async function doAction() {
await execute({
id: id,
})
console.log(data) // doesn't work, return stale data instead of waiting for execute to finish updating state
}
Of course I can use useEffect but I prefer not to.
2 replies
TTCTheo's Typesafe Cult
Created by Luc Ledo on 7/29/2023 in #questions
Why Use Server Actions?
I can see the benefit of the server component version. Colocated, no need to make an api endpoint in another file.
import { cookies } from 'next/headers'

// Server action defined inside a Server Component
export default function AddToCart({ productId }) {
async function addItem(data) {
'use server'

const cartId = cookies().get('cartId')?.value
await saveToDb({ cartId, data })
}

return (
<form action={addItem}>
<button type="submit">Add to Cart</button>
</form>
)
}
import { cookies } from 'next/headers'

// Server action defined inside a Server Component
export default function AddToCart({ productId }) {
async function addItem(data) {
'use server'

const cartId = cookies().get('cartId')?.value
await saveToDb({ cartId, data })
}

return (
<form action={addItem}>
<button type="submit">Add to Cart</button>
</form>
)
}
But isn't the client component version just another way of writing API endpoints?
'use server'

export async function addItem(data) {
const cartId = cookies().get('cartId')?.value
await saveToDb({ cartId, data })
}
'use server'

export async function addItem(data) {
const cartId = cookies().get('cartId')?.value
await saveToDb({ cartId, data })
}
Guess you can use it in form without javascript:
'use client'

import { addItem } from './actions.js'

// Server Action being called inside a Client Component
export default function AddToCart({ productId }) {
return (
<form action={addItem}>
<button type="submit">Add to Cart</button>
</form>
)
}
'use client'

import { addItem } from './actions.js'

// Server Action being called inside a Client Component
export default function AddToCart({ productId }) {
return (
<form action={addItem}>
<button type="submit">Add to Cart</button>
</form>
)
}
But using it this way feels sucky as there is no way (that I know of) to make it typesafe.
4 replies
TTCTheo's Typesafe Cult
Created by Luc Ledo on 7/28/2023 in #questions
Does server actions input have to be validated server side?
Are they like exposed api endpoints or are they private? Would validating client side using input props like require/max-length work?
2 replies
TTCTheo's Typesafe Cult
Created by Luc Ledo on 7/24/2023 in #questions
This Shouldn't Work But It Does🤔
https://github.com/Apestein/async-client-demo/tree/main
"use client"

type Todo = {
userId: number
id: number
title: string
completed: boolean
}
async function getData() {
const res = await fetch("https://jsonplaceholder.typicode.com/todos/1")
if (!res.ok) throw new Error("failed to fetch")
return res.json() as Promise<Todo>
}

export async function AsyncClient() {
const todo = await getData()
console.log(todo) //this gets logged to client
return (
<div className="flex flex-col gap-3 border p-3">
Async Client Component
<button className="border" onClick={() => console.log("clicked")}>
Button
</button>
Todo: {todo.id}
</div>
)
}
"use client"

type Todo = {
userId: number
id: number
title: string
completed: boolean
}
async function getData() {
const res = await fetch("https://jsonplaceholder.typicode.com/todos/1")
if (!res.ok) throw new Error("failed to fetch")
return res.json() as Promise<Todo>
}

export async function AsyncClient() {
const todo = await getData()
console.log(todo) //this gets logged to client
return (
<div className="flex flex-col gap-3 border p-3">
Async Client Component
<button className="border" onClick={() => console.log("clicked")}>
Button
</button>
Todo: {todo.id}
</div>
)
}
This is an async client component, this should not work and yet it does. The console.log will show up on client. It will not let you use useState but onClick will work. If you do export default async function instead then it will give you an error as expected but export async function will work.
7 replies
TTCTheo's Typesafe Cult
Created by Luc Ledo on 7/23/2023 in #questions
Clerk Forces All Routes To Be Dynamic
7 replies
TTCTheo's Typesafe Cult
Created by Luc Ledo on 7/17/2023 in #questions
Intercepting Modal Cause Jump To Bottom Of Page
4 replies