MiNiMAL
MiNiMAL15mo ago

Dynamic input not leading to changes on the front end

I'm building a dynamic procedure to access my database via Drizzle ORM. Ideally a developer would be able to send input parameters to the procedure and have it's output adjusted by that input. For example, in the below, I have a table called demotable which has an updatedAt column. If a developer passes in columns: { updatedAt: false } to the procedure, then ideally the column would not get included in the result. If I hard code the columns parameter in the backend itself, then it works great. Is there a way to accomplish this for the full round trip?
// Inferring type for the findMany argument
type FindManyArg = Parameters<DB['query']['demotable']['findMany']>[0]

// ...

//Setting up the procedure
discordTest: privateProcedure
.input(input => input as FindManyArg)
.query(async ({ input }) => {
const result = await db.query.demotable.findMany(input)
return result
}),

// On the front end,
const { data: demo } = trpc.discordTest.useQuery({
columns: { updatedAt: false }, // <== this is properly typed and intellisense is working
})
console.log(demo?.[0].updatedAt) // <=== does not error

// ============================

// Hardcoding columns does properly reflect on the front end
const result = await db.query.demotable.findMany({
...input,
columns: { updatedAt: false },
})
return result

// On the front end,
const { data: demo } = trpc.discordTest.useQuery({})
console.log(demo?.[0].updatedAt) // <=== errors as expected
// Inferring type for the findMany argument
type FindManyArg = Parameters<DB['query']['demotable']['findMany']>[0]

// ...

//Setting up the procedure
discordTest: privateProcedure
.input(input => input as FindManyArg)
.query(async ({ input }) => {
const result = await db.query.demotable.findMany(input)
return result
}),

// On the front end,
const { data: demo } = trpc.discordTest.useQuery({
columns: { updatedAt: false }, // <== this is properly typed and intellisense is working
})
console.log(demo?.[0].updatedAt) // <=== does not error

// ============================

// Hardcoding columns does properly reflect on the front end
const result = await db.query.demotable.findMany({
...input,
columns: { updatedAt: false },
})
return result

// On the front end,
const { data: demo } = trpc.discordTest.useQuery({})
console.log(demo?.[0].updatedAt) // <=== errors as expected
2 Replies
Zhou (Link) Fang
Zhou (Link) Fang13mo ago
Having the same issue using Prisma. I think this is a common usage, not sure how everyone solves this issue? Quite some tables might have relationships with other tables and those properties will not be included in the query data by default. But we can pass "include" to include those additional info when needed and unfortunately, trpc will not infer the type on the fly based on the actual input when we do the query, but just using the default type... e.g., a person item would be { name: 'Bob', title: 'Developer' } or { name: 'Bob', title: 'Developer', projects: [{name: 'project a'}, {name: 'project b'}] }
Zhou (Link) Fang
Zhou (Link) Fang13mo ago
Just found a similar question and sadly the answer is no, dynamically infer type based on input is not doable atm. Reference: https://trpc.io/docs/faq#can-i-dynamically-return-a-different-output-depending-on-what-input-i-send Simiar question: https://discord.com/channels/867764511159091230/1131680860387684422/1132657491516346468
FAQ / Troubleshooting | tRPC
Collection of frequently asked questions with ideas on how to troubleshoot & resolve them.