holden
holden16mo ago

optional fields

I have a field of type v.optional(v.string()). How can I set the value to undefined? When I call db.patch with value: undefined, that seems to have no effect?
4 Replies
lee
lee16mo ago
hi! this should work. Can you share more of your code? One quick note is you can't, strictly speaking, store undefined in convex. But you can store an object that does not have a field. So db.patch(id, {foo: undefined}) will remove the field foo from the document id.
holden
holdenOP16mo ago
sure! storing as "unset" is fine. Here's my mutation (omitting some irrelevant parts):
export const update = mutation({
args: {
id: v.id("projects"),
...
themeId: v.optional(v.union(v.id("themes"), v.string())),
},
handler: async (ctx, args) => {
const { id, ...rest } = args;
console.log("args", args)
...
const now = new Date().getTime();
await ctx.db.patch(id, { ...rest, updatedTime: now });
},
});
export const update = mutation({
args: {
id: v.id("projects"),
...
themeId: v.optional(v.union(v.id("themes"), v.string())),
},
handler: async (ctx, args) => {
const { id, ...rest } = args;
console.log("args", args)
...
const now = new Date().getTime();
await ctx.db.patch(id, { ...rest, updatedTime: now });
},
});
Calling it in a React client component like this:
const updateProject = useMutation(api.projects.update);
...
await updateProject({ id: project?._id, themeId: undefined });
const updateProject = useMutation(api.projects.update);
...
await updateProject({ id: project?._id, themeId: undefined });
When I console.log the args, I only get the id field, nothing for themeId:
log
'args' {
id: '346mvg6cp5apqwz2s5vvemws9jjhkh0'
}
log
'args' {
id: '346mvg6cp5apqwz2s5vvemws9jjhkh0'
}
lee
lee16mo ago
Ah i see. This is expected. There's only a slight difference between {} and {themeId: undefined}, and since the value is being sent from client to server, undefined values are dropped (like JSON.stringify will do). To make your code work, you can explicitly destructure optional args. const { id, themeId, ...rest } = args; await ctx.db.patch(id, {...rest, themeId, updatedTime: now}) Or you can do something that looks a bit silly: args.themeId = args.themeId; at the beginning of your function should work. Javascript... is interesting
holden
holdenOP16mo ago
Ok, makes sense, thanks for the explanation!

Did you find this page helpful?