stevanfreeborn
stevanfreeborn17mo ago

Help Debugging

Would someone be able to help me debug this error:
Error: [CONVEX Q(posts.js:getPostsBySearchTerm)] Uncaught Error: Must provide arg 2 `value` to `search`
at <anonymous> (../convex/posts.ts:196:35)
at handler (../convex/posts.ts:193:23)

Called by client
Error: [CONVEX Q(posts.js:getPostsBySearchTerm)] Uncaught Error: Must provide arg 2 `value` to `search`
at <anonymous> (../convex/posts.ts:196:35)
at handler (../convex/posts.ts:193:23)

Called by client
Here is my query:
export const getPostsBySearchTerm = query({
args: { term: v.string(), paginationOpts: paginationOptsValidator },
handler: async (ctx, args) => {
const posts = await ctx.db
.query('posts')
.withSearchIndex('search_by_content',
q => q.search('content', args.term).eq('parentPostId', undefined)
)
.paginate(args.paginationOpts);

const postsWithUser = await getPostsWithUsers({ ctx, posts: posts.page });

return { ...posts, page: postsWithUser };
},
});

async function getPostsWithUsers({
ctx,
posts,
}: {
ctx: QueryCtx;
posts: Doc<'posts'>[];
}) {
return await Promise.all(
posts.map(async post => {
const user = await ctx.db.get(post.userId);

if (user === null) {
return {
...post,
user: {
_id: '' as Id<'users'>,
_creationTime: 0,
clerkUsername: null,
clerkImageUrl: '',
clerkUserId: '',
},
};
}

return {
...post,
user: {
_id: user._id,
_creationTime: user._creationTime,
clerkUsername: user.clerkUser.username,
clerkImageUrl: user.clerkUser.image_url,
clerkUserId: user.clerkUser.id,
},
};
})
);
}
export const getPostsBySearchTerm = query({
args: { term: v.string(), paginationOpts: paginationOptsValidator },
handler: async (ctx, args) => {
const posts = await ctx.db
.query('posts')
.withSearchIndex('search_by_content',
q => q.search('content', args.term).eq('parentPostId', undefined)
)
.paginate(args.paginationOpts);

const postsWithUser = await getPostsWithUsers({ ctx, posts: posts.page });

return { ...posts, page: postsWithUser };
},
});

async function getPostsWithUsers({
ctx,
posts,
}: {
ctx: QueryCtx;
posts: Doc<'posts'>[];
}) {
return await Promise.all(
posts.map(async post => {
const user = await ctx.db.get(post.userId);

if (user === null) {
return {
...post,
user: {
_id: '' as Id<'users'>,
_creationTime: 0,
clerkUsername: null,
clerkImageUrl: '',
clerkUserId: '',
},
};
}

return {
...post,
user: {
_id: user._id,
_creationTime: user._creationTime,
clerkUsername: user.clerkUser.username,
clerkImageUrl: user.clerkUser.image_url,
clerkUserId: user.clerkUser.id,
},
};
})
);
}
And then calling it from the frontend
const postsPager = usePaginatedQuery(
api.posts.getPostsBySearchTerm,
{ term },
{ initialNumItems: PAGE_SIZE }
);
const postsPager = usePaginatedQuery(
api.posts.getPostsBySearchTerm,
{ term },
{ initialNumItems: PAGE_SIZE }
);
10 Replies
ballingt
ballingt17mo ago
The error message says "must provide arg 2 to search" so I'd try console.log-ing args.term on the previous line to see what it is, since that's what you're passing as the second argument to search(). Also double-check that npm run dev or npx convex dev or however you keep convex functions updating is running
stevanfreeborn
stevanfreebornOP17mo ago
Okay sounds good. I tried console logging args last night and saw the term which is what made me confused. I’ll try again fresh this morning and give ‘er another go.
sshader
sshader17mo ago
Does removing the .eq('parentPostId', undefined) give the same error (or replacing it with something other than undefined)? If not, this sounds like a bug on our end
stevanfreeborn
stevanfreebornOP17mo ago
So I console logged args in the query and I get this:
[CONVEX Q(posts.js:getPostsBySearchTerm)] [LOG] {
paginationOpts: {
cursor: null,
id: 2,
numItems: 10
},
term: 'Hello'
}
[CONVEX Q(posts.js:getPostsBySearchTerm)] [LOG] {
paginationOpts: {
cursor: null,
id: 2,
numItems: 10
},
term: 'Hello'
}
Which is what I expect And when I remove the .eq() call the error stops being thrown. If I pass an empty string to the eq() call instead of undefined the error also does not get thrown.
ballingt
ballingt17mo ago
Oh yeah that's it, it's that undefined! .eq('parentPostId', undefined) Sorry, the error message should be about eq, not search
stevanfreeborn
stevanfreebornOP17mo ago
I'm for now just going with a filter() call after the withSearchIndex call and that seems to be working, but I think if I could do that filtering within the search it might be more performant. Is undefined as an argument not supported within that method?
ballingt
ballingt17mo ago
I don't think this syntax allows searching for something to be equal to undefined, what is it you're trying to do here? you're looking for results where that field doesn't exist? parentPostId is optional these records?
stevanfreeborn
stevanfreebornOP17mo ago
Yeah exactly basically I have posts that can also potentially be replies to other posts based on whether they have a parent or not. When I'm searching I just want to consider posts that are truly just parents only. And I was going based off this statement on this page of the docs:
To filter to documents that are missing a field, use q.eq("fieldName", undefined).
To filter to documents that are missing a field, use q.eq("fieldName", undefined).
https://docs.convex.dev/text-search#equality-expressions Which does seem to work in other filter expressions okay.
ballingt
ballingt17mo ago
Cool, I'll look into this — the library code validates that that argument is not undefined, it could be that this isn't supported or it could be we're just validating too strictly.
stevanfreeborn
stevanfreebornOP17mo ago
Oh no worries at all. I really appreciate you guys being so willing to help me especially on a Saturday morning. I think I'm all square now for what I need to accomplish. 🙏

Did you find this page helpful?