I am currently utilizing Prisma version 4.2.1 within a Next.js API Route to implement cursor-based pagination for posts.
Upon passing the cursor to the API endpoint, I encounter an error message (500) in the console:
TypeError: Cannot read properties of undefined (reading 'createdAt')
at getPost (webpack-internal:///(api)/./lib/api/post.ts:67:46)
error - TypeError [ERR_INVALID_ARG_TYPE]: The "string" argument must be of type string or an instance of Buffer or ArrayBuffer. Received an instance of TypeError
To access the API endpoint, I utilize Postman.
If I remove the cursor from the API Route, the errors disappear and the posts are returned correctly.
Although I have attempted various solutions including upgrading to Prisma version 4.2.1, using .toString() on the cursor, and modifying the AllPosts interface to 'any', I have been unsuccessful in resolving the TypeError.
Could someone guide me on rectifying this error and successfully having Prisma acknowledge the cursor as valid?
API Route
import prisma from "@/lib/prisma";
import type { NextApiRequest, NextApiResponse } from "next";
import type { Post, Site } from ".prisma/client";
import type { Session } from "next-auth";
import { revalidate } from "@/lib/revalidate";
import type { WithSitePost } from "@/types";
interface AllPosts {
posts: Array<Post>;
site: Site | null;
}
export async function getPost(
req: NextApiRequest,
res: NextApiResponse,
session: Session
): Promise<void | NextApiResponse<AllPosts | (WithSitePost | null)>> {
const { postId, siteId, published, cursor } = req.query;
if (
Array.isArray(postId) ||
Array.isArray(siteId) ||
Array.isArray(published) ||
Array.isArray(cursor)
)
return res.status(400).end("Bad request. Query parameters are not valid.");
if (!session.user.id)
return res.status(500).end("Server failed to get session user ID");
try {
if (postId) {
const post = await prisma.post.findFirst({
where: {
id: postId,
site: {
user: {
id: session.user.id,
},
},
},
include: {
site: true,
},
});
return res.status(200).json(post);
}
const site = await prisma.site.findFirst({
where: {
id: siteId,
user: {
id: session.user.id,
},
},
});
const posts = !site
? []
: await prisma.post.findMany({
take: 10,
skip: cursor === undefined ? 0 : 1,
cursor: {
id: cursor,
},
where: {
site: {
id: siteId,
},
published: JSON.parse(published || "true"),
},
orderBy: {
createdAt: "desc",
},
});
const lastPostInResults = posts[9];
const nextCursor = lastPostInResults.createdAt;
return res.status(200).json({
posts,
site,
nextCursor,
});
} catch (error) {
console.error(error);
return res.status(500).end(error);
}
}
Prisma Schema
model Post {
id String @id @default(cuid())
title String? @db.Text
content String? @db.LongText
slug String @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
published Boolean @default(false)
site Site? @relation(fields: [siteId], references: [id], onDelete: Cascade)
siteId String?
@@unique([id, siteId], name: "post_site_constraint")
}
model Site {
id String @id @default(cuid())
name String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User? @relation(fields: [userId], references: [id])
userId String?
posts Post[]
}