star ✨
star ✨2y ago

Patch not typechecking

for now i do a db.get and fill any missing values in the db.patch with those values but idk y i need to do 2 queries for the sake of typescript??
6 Replies
ballingt
ballingt2y ago
@star ✨ Could you share your code or a small sample that's enough to repro? Sounds frustrating, this isn't a known issue so would love to get a repro.
star ✨
star ✨OP2y ago
Glad you're taking a look at it! I'll share the relevant code like so : For context - nodes are literally nodes on a canvas on my app - theres different kinds of nodes - ones that store text, links etc... convex/nodes.ts
export const updateTextNode = mutation({
args: {
id: v.id("nodes"),
text: v.optional(v.string()),
x: v.optional(v.number()),
y: v.optional(v.number()),
width: v.optional(v.float64()),
},
handler: async (ctx, args) => {
const identity = await ctx.auth.getUserIdentity();
if (identity === null) {
return null;
}
// To get the type error to go away i had to do a get so I can pass all the values that are missing in args to the patch and that made the type error go away
const node = await ctx.db.get(args.id);
if (node?.type == "text") {
const newNodeId = await ctx.db.patch(args.id, {
text: args.text ?? node?.text,
x: args.x ?? node?.x,
y: args.y ?? node?.y,
width: args.width ?? node?.width,
});
return newNodeId;
}
return null;
},
});
export const updateTextNode = mutation({
args: {
id: v.id("nodes"),
text: v.optional(v.string()),
x: v.optional(v.number()),
y: v.optional(v.number()),
width: v.optional(v.float64()),
},
handler: async (ctx, args) => {
const identity = await ctx.auth.getUserIdentity();
if (identity === null) {
return null;
}
// To get the type error to go away i had to do a get so I can pass all the values that are missing in args to the patch and that made the type error go away
const node = await ctx.db.get(args.id);
if (node?.type == "text") {
const newNodeId = await ctx.db.patch(args.id, {
text: args.text ?? node?.text,
x: args.x ?? node?.x,
y: args.y ?? node?.y,
width: args.width ?? node?.width,
});
return newNodeId;
}
return null;
},
});
canvas/schema.ts
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";

const CanvasNode = {
x: v.number(),
y: v.number(),
width: v.float64(),
height: v.optional(v.float64()),
createdBy: v.string(),
};

export default defineSchema({
nodes: defineTable(
v.union(
v.object({
type: v.literal("text"),
text: v.string(),
...CanvasNode,
}),
v.object({
type: v.literal("url"),
url: v.string(),
...CanvasNode,
})
)
),
});
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";

const CanvasNode = {
x: v.number(),
y: v.number(),
width: v.float64(),
height: v.optional(v.float64()),
createdBy: v.string(),
};

export default defineSchema({
nodes: defineTable(
v.union(
v.object({
type: v.literal("text"),
text: v.string(),
...CanvasNode,
}),
v.object({
type: v.literal("url"),
url: v.string(),
...CanvasNode,
})
)
),
});
on the client: components/node.tsx (example component - not exactly what i did but close)
const Node = ({convexId}:{convexId:Id<"nodes">})=>{
const updateNode = useMutation(api.nodes.updateTextNode);

const [position,setPosition]

useEffect(()=>{
if(position)
updateNode({
id: convexId,
x: position.x,
y: position.y,
});
},[JSON.stringify(position)])

//...rest of the component
}
const Node = ({convexId}:{convexId:Id<"nodes">})=>{
const updateNode = useMutation(api.nodes.updateTextNode);

const [position,setPosition]

useEffect(()=>{
if(position)
updateNode({
id: convexId,
x: position.x,
y: position.y,
});
},[JSON.stringify(position)])

//...rest of the component
}
Hopefully this gives you enough context? let me know if you require anything else
ballingt
ballingt2y ago
Could you send a version of the code with the error? vs this already fixed version Error messages with schema errors on unions could use improving, it's harder to infer intent with unions.
star ✨
star ✨OP2y ago
what do you mean version of the code?
ballingt
ballingt2y ago
Sorry been out, I mean it would help me understand the error to see the code like
handler: async (ctx, args) => {
// To get the type error to go away i had to do a get so I can pass all the values that are missing in args to the patch and that made the type error go away
const node = await ctx.db.get(args.id);
if (node?.type == "text") {
const newNodeId = await ctx.db.patch(args.id, {
text: args.text ?? node?.text,
x: args.x ?? node?.x,
y: args.y ?? node?.y,
width: args.width ?? node?.width,
});
return newNodeId;
}
return null;
},
handler: async (ctx, args) => {
// To get the type error to go away i had to do a get so I can pass all the values that are missing in args to the patch and that made the type error go away
const node = await ctx.db.get(args.id);
if (node?.type == "text") {
const newNodeId = await ctx.db.patch(args.id, {
text: args.text ?? node?.text,
x: args.x ?? node?.x,
y: args.y ?? node?.y,
width: args.width ?? node?.width,
});
return newNodeId;
}
return null;
},
where you had a type error, to see the code that you wanted to work
star ✨
star ✨OP2y ago
Ah gotcha Hold on

Did you find this page helpful?