[TRPC or Prisma or React Native issue?] Do not know how to serialize a BigInt
I og started a thread on the TRPC discord but am also posting here to see if anyone else has a better solution for this issue. I am trying to figure out exactly where this issue originated from.
OG link: https://discord.com/channels/867764511159091230/1110257286707937380/1110257286707937380
I am calling a trpc query in a component based on a currently selected item in a flatlist, and getting error:
TypeError: Do not know how to serialize a BigInt
TypeError: Do not know how to serialize a BigInt
3 Replies
The component code:
the lesson router:
the database wp_postmeta table:
my packages/api/src/trpc.ts file with the superjson transformer:
the error only goes away when i add this code to the top of my component file:
import React, { useState, useRef, FC } from "react";
... other imports
import { trpc } from "../../../utils/trpc";
interface CourseComponentProps {
data?: DataItem[];
}
type DataItem = {
ID: bigint;
post_title: string;
videoUri?: string;
};
type ItemProps = {
item: DataItem;
onPress: () => void;
};
const Item = ({ item, onPress }: ItemProps) => (
<TouchableOpacity
className="bg-blueGray-300 border-1 justify-center p-3"
onPress={onPress}
>
<Text className="text-blueGray-800">{item.post_title}</Text>
</TouchableOpacity>
);
export const CourseComponent: FC<CourseComponentProps> = ({ data }) => {
const video = React.useRef(null);
const [currentItem, setCurrentItem] = React.useState<DataItem>();
const { data: videoData, error } = trpc.lesson.videoUri.useQuery(
currentItem?.ID as bigint,
{
enabled: !!currentItem?.ID,
},
);
if (error) {
// Handle error
return <View>Error: {error.message}</View>;
}
const metaValue = videoData?.meta_value;
console.log("metaValue", metaValue);
console.log("currentItemId", currentItem?.ID);
const renderItem = ({ item }: { item: DataItem }) => {
return <Item item={item} onPress={() => setCurrentItem(item)} />;
};
return (
<View className="h-screen w-[100%]">
<Video
ref={video}
style={styles.video}
source={{
uri: metaValue || "",
}}
useNativeControls
resizeMode={ResizeMode.CONTAIN}
isLooping
/>
<Text>{currentItem?.post_title}</Text>
<FlashList
data={data}
renderItem={renderItem}
keyExtractor={(item) => item.ID.toString()}
/>
</View>
);
};
CourseComponent.defaultProps = {
data: [
{
ID: BigInt(1),
post_title: "Default Post Title 1",
videoUri: "https://d23dyxeqlo5psv.cloudfront.net/big_buck_bunny.mp4",
},
...
],
};
import React, { useState, useRef, FC } from "react";
... other imports
import { trpc } from "../../../utils/trpc";
interface CourseComponentProps {
data?: DataItem[];
}
type DataItem = {
ID: bigint;
post_title: string;
videoUri?: string;
};
type ItemProps = {
item: DataItem;
onPress: () => void;
};
const Item = ({ item, onPress }: ItemProps) => (
<TouchableOpacity
className="bg-blueGray-300 border-1 justify-center p-3"
onPress={onPress}
>
<Text className="text-blueGray-800">{item.post_title}</Text>
</TouchableOpacity>
);
export const CourseComponent: FC<CourseComponentProps> = ({ data }) => {
const video = React.useRef(null);
const [currentItem, setCurrentItem] = React.useState<DataItem>();
const { data: videoData, error } = trpc.lesson.videoUri.useQuery(
currentItem?.ID as bigint,
{
enabled: !!currentItem?.ID,
},
);
if (error) {
// Handle error
return <View>Error: {error.message}</View>;
}
const metaValue = videoData?.meta_value;
console.log("metaValue", metaValue);
console.log("currentItemId", currentItem?.ID);
const renderItem = ({ item }: { item: DataItem }) => {
return <Item item={item} onPress={() => setCurrentItem(item)} />;
};
return (
<View className="h-screen w-[100%]">
<Video
ref={video}
style={styles.video}
source={{
uri: metaValue || "",
}}
useNativeControls
resizeMode={ResizeMode.CONTAIN}
isLooping
/>
<Text>{currentItem?.post_title}</Text>
<FlashList
data={data}
renderItem={renderItem}
keyExtractor={(item) => item.ID.toString()}
/>
</View>
);
};
CourseComponent.defaultProps = {
data: [
{
ID: BigInt(1),
post_title: "Default Post Title 1",
videoUri: "https://d23dyxeqlo5psv.cloudfront.net/big_buck_bunny.mp4",
},
...
],
};
import { router, publicProcedure, protectedProcedure } from "../trpc";
import { z } from "zod";
export const lessonRouter = router({
all: publicProcedure.query(({ ctx }) => {
return ctx.prisma.wp_posts.findMany({
where: {
post_type: "sfwd-lessons",
},
});
}),
videoUri: publicProcedure.input(z.bigint()).query(({ ctx, input }) => {
return ctx.prisma.wp_postmeta.findFirst({
where: {
post_id: input, // Change the post_id value here
meta_key: "app_video_uri", // Replace "video_uri" with the actual meta_key for the meta_value you want to retrieve
},
});
}),
});
import { router, publicProcedure, protectedProcedure } from "../trpc";
import { z } from "zod";
export const lessonRouter = router({
all: publicProcedure.query(({ ctx }) => {
return ctx.prisma.wp_posts.findMany({
where: {
post_type: "sfwd-lessons",
},
});
}),
videoUri: publicProcedure.input(z.bigint()).query(({ ctx, input }) => {
return ctx.prisma.wp_postmeta.findFirst({
where: {
post_id: input, // Change the post_id value here
meta_key: "app_video_uri", // Replace "video_uri" with the actual meta_key for the meta_value you want to retrieve
},
});
}),
});
model wp_postmeta {
meta_id BigInt @id @default(autoincrement()) @db.UnsignedBigInt
post_id BigInt @default(0) @db.UnsignedBigInt
meta_key String? @db.VarChar(255)
meta_value String? @db.LongText
@@index([meta_key(length: 191)], map: "meta_key")
@@index([post_id], map: "post_id")
}
model wp_postmeta {
meta_id BigInt @id @default(autoincrement()) @db.UnsignedBigInt
post_id BigInt @default(0) @db.UnsignedBigInt
meta_key String? @db.VarChar(255)
meta_value String? @db.LongText
@@index([meta_key(length: 191)], map: "meta_key")
@@index([post_id], map: "post_id")
}
import { initTRPC, TRPCError } from "@trpc/server";
import { type Context } from "./context";
import superjson from "superjson";
const t = initTRPC.context<Context>().create({
transformer: superjson,
errorFormatter({ shape }) {
return shape;
},
});
const isAuthed = t.middleware(({ next, ctx }) => {
if (!ctx.auth.userId) {
throw new TRPCError({ code: "UNAUTHORIZED", message: "Not authenticated" });
}
return next({
ctx: {
auth: ctx.auth,
},
});
});
export const router = t.router;
export const publicProcedure = t.procedure;
export const protectedProcedure = t.procedure.use(isAuthed);
import { initTRPC, TRPCError } from "@trpc/server";
import { type Context } from "./context";
import superjson from "superjson";
const t = initTRPC.context<Context>().create({
transformer: superjson,
errorFormatter({ shape }) {
return shape;
},
});
const isAuthed = t.middleware(({ next, ctx }) => {
if (!ctx.auth.userId) {
throw new TRPCError({ code: "UNAUTHORIZED", message: "Not authenticated" });
}
return next({
ctx: {
auth: ctx.auth,
},
});
});
export const router = t.router;
export const publicProcedure = t.procedure;
export const protectedProcedure = t.procedure.use(isAuthed);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(BigInt.prototype as any).toJSON = function () {
return Number(this);
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(BigInt.prototype as any).toJSON = function () {
return Number(this);
};
Did you found a way to fix this? I've got this too. create-t3-app use superjson by default, I don't know why trpc throw this error