ArgumentValidationError: Object is missing the required field `numItems
ERROR:
// backend
// frontend
Error: [CONVEX Q(user:getThreads)] ArgumentValidationError: Object is missing the required field `numItems`. Consider wrapping the field validator in `v.optional(...)` if this is expected.
Path: .paginationOpts
Object: {cursor: "0783738008d9b382ca0ba467ff5e71bc8eda02090a165d0dc90391a90916daa27cc2b854de242c61da89990042c8fcacc25022b6df1d9a6c9bd3fd512ee0716493d2f68a7a189e3d2a9b96acc53d75433fb28bb9fec47fa4c3cb2d1d233c25e491440c02b0fb9bf201eceb7be3e6adf9952385e8b7479930adee14cf645c1bce29e6d7081618158a856183f3d1a325", id: 1.0}
Validator: v.object({cursor: v.union(v.string(), v.null()), endCursor: v.optional(v.union(v.string(), v.null()))Error: [CONVEX Q(user:getThreads)] ArgumentValidationError: Object is missing the required field `numItems`. Consider wrapping the field validator in `v.optional(...)` if this is expected.
Path: .paginationOpts
Object: {cursor: "0783738008d9b382ca0ba467ff5e71bc8eda02090a165d0dc90391a90916daa27cc2b854de242c61da89990042c8fcacc25022b6df1d9a6c9bd3fd512ee0716493d2f68a7a189e3d2a9b96acc53d75433fb28bb9fec47fa4c3cb2d1d233c25e491440c02b0fb9bf201eceb7be3e6adf9952385e8b7479930adee14cf645c1bce29e6d7081618158a856183f3d1a325", id: 1.0}
Validator: v.object({cursor: v.union(v.string(), v.null()), endCursor: v.optional(v.union(v.string(), v.null()))// backend
export const getThreads = query({
args: {
districtsId: v.union(v.id("districts"), v.null()),
timeFrame: v.union(
v.literal("week"),
v.literal("month"),
v.literal("year"),
v.literal("allTime")
), // 'day', 'month', 'year', 'allTime'
filter: v.union(
v.literal("points"),
v.literal("hearts"),
v.literal("laughs"),
v.literal("likes"),
v.literal("dislikes")
),
paginationOpts: paginationOptsValidator,
},
handler: async (
{ db },
{ districtsId, timeFrame, filter, paginationOpts }
) => {
const timeFrameStart = calculateTimestamp(timeFrame);
let threads;
threads = await db
.query("threads")
// .withIndex(`by_districtsId_postDate_${filter}`, (q) =>
// q.eq("districtsId", districtsId).gte("postDate", timeFrameStart)
// )
.order("desc")
.paginate(paginationOpts);
return threads;
},
});export const getThreads = query({
args: {
districtsId: v.union(v.id("districts"), v.null()),
timeFrame: v.union(
v.literal("week"),
v.literal("month"),
v.literal("year"),
v.literal("allTime")
), // 'day', 'month', 'year', 'allTime'
filter: v.union(
v.literal("points"),
v.literal("hearts"),
v.literal("laughs"),
v.literal("likes"),
v.literal("dislikes")
),
paginationOpts: paginationOptsValidator,
},
handler: async (
{ db },
{ districtsId, timeFrame, filter, paginationOpts }
) => {
const timeFrameStart = calculateTimestamp(timeFrame);
let threads;
threads = await db
.query("threads")
// .withIndex(`by_districtsId_postDate_${filter}`, (q) =>
// q.eq("districtsId", districtsId).gte("postDate", timeFrameStart)
// )
.order("desc")
.paginate(paginationOpts);
return threads;
},
});// frontend
const {
results: serverThreads,
status,
isLoading,
loadMore,
} = usePaginatedQuery(
api.user.getThreads,
{
districtsId: district.districtsId,
timeFrame: timeFrame,
filter: filter,
},
{ initialNumItems: 2 }
); const {
results: serverThreads,
status,
isLoading,
loadMore,
} = usePaginatedQuery(
api.user.getThreads,
{
districtsId: district.districtsId,
timeFrame: timeFrame,
filter: filter,
},
{ initialNumItems: 2 }
);