Open RedEagle-dh opened 1 month ago
Here you can see the error from the frontend where the transformer does not match because I should place a transformer in the backend too (which I did) :D
Hey again, the issue was on my side because my prisma model was not in sync with the database. The database gave me []
instead of {}
which came from the model... Lost literally 5 hours on this one.
Anyway, it worked without an external superjson library! But I am still confused, why the transformer does not get passed into the generated file.
Hey again, the issue was on my side because my prisma model was not in sync with the database. The database gave me
[]
instead of{}
which came from the model... Lost literally 5 hours on this one.Anyway, it worked without an external superjson library! But I am still confused, why the transformer does not get passed into the generated file.
Hey, Thanks for opening an issue! Sorry you had to debug things for such a long time, you could always ping me in discord and I'll do my best to help if i'm not here, theres a link for the channel in the repo readme.
For your issue, we don't pass the data transform because I didn't know it was needed, but I can write an implementation for it if needed.
Do you mind giving me a sample code of what the generated server.ts
file would look like with that transformer applied?
Sure thing!
When I want to use for example the superjson transformer, I want to add it through the existing field in the app.module.ts:
// app.module.ts
import { TRPCModule } from 'nestjs-trpc';
import { AppContext } from './app.context';
import SuperJSON from 'superjson';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
}),
TRPCModule.forRoot({
autoSchemaFile: './src/@generated',
context: AppContext,
transformer: SuperJSON,
}),
DbModule,
],
controllers: [AppController],
providers: [AppService, DbService, AppContext, AppRouter],
})
export class AppModule {}
The auto generated server.ts file could look like this:
// src/@generated/server.ts
import { initTRPC } from "@trpc/server";
import { z } from "zod";
import { SuperJSON } from "superjson"; // this import depends on the module resolution in the tsconfig but you could just copy the import statement and paste it in the server.ts
const t = initTRPC.create({
transformer: SuperJSON // the transformer object has a "serialize" and a "deserialize" field which is important. You could create an own transformer and it should be possible to use that too
});
const publicProcedure = t.procedure;
const appRouter = t.router({
app: t.router({
findAll: publicProcedure.output(z.array(z.object({
twitch_id: z.string().max(32),
username: z.string().max(25),
join_date: z.date().default(() => new Date()),
jdeleted_at: z.date().optional(),
email: z.string(),
publish_stats: z.boolean().default(false),
flags: z.array(z.any()).optional().default([]),
}))).query(async () => "PLACEHOLDER_DO_NOT_REMOVE" as any)
})
});
export type AppRouter = typeof appRouter;
Another way is to pass a self created transformer into the create method, like I mentioned it in the comment.
Here is an example with superjson but split into it's core functions:
// src/@generated/server.ts (snippet)
import { SuperJSON } from "superjson";
const t = initTRPC.create({
transformer: {
serialize: SuperJSON.serialize,
deserialize: SuperJSON.deserialize,
}
});
PS: I was able to create a little workaround by commenting autoSchemaFile: './src/@generated',
out, adding the exact same code you can find here to the generated file and then start the server. After that, it worked as well.
Thats totally doable, I'll try to implement this this week/on the weekend.
Sounds nice! Thanks for your work, your adapter is implemented in my project already :D
Glad to find this. I ran into the same issue right now. Thanks for the solving. :)
Quick update, I am still working on this, I managed to get a simple import data transformer to work, but I want to make something more generalized, so it will take more time.
Hey there!
First of all, I like your adapter very much and the idea how you implement trcp in nestjs is great! Sad that it did not came from the trpc devs.
Anyway, I use the T3 techstack with Nestjs as the backend.
My problem is, that I have some complex data structures and without a data transformer trpc seems to have problems with passing data into the frontend.
I tried it with a simple test structure with one field and that worked!
But if I wanted to pass a whole entity with some nested fields and especially date types, I get an error saying: "output validation failed".
My steps to fix this error
@Module({ imports: [ ConfigModule.forRoot({ isGlobal: true, }), TRPCModule.forRoot({ autoSchemaFile: './src/@generated', context: AppContext, transformer: SuperJSON, }), DbModule, ], controllers: [AppController], providers: [AppService, DbService, AppContext, AppRouter], }) export class AppModule {}
Well, here is a weird thing: The TRPCClient does not see the transformer from the backend. But as you see, I added one. So maybe it must be expose in other way to the AppContext or idk. Unfortunately I didn't found any documentation regarding this.
Could you please help me with that?