Gorka Cesium
Gorka Cesium2y ago

patch nested object

items: defineTable(
v.object({
quote: v.id("quotes"),
tag: v.literal("ItemType1")
value: v.object({
name: v.string()
reference: v.string()
})
})
)
items: defineTable(
v.object({
quote: v.id("quotes"),
tag: v.literal("ItemType1")
value: v.object({
name: v.string()
reference: v.string()
})
})
)
how can I write a mutation to patch value without having to input all the fields? for example
patch(itemId, {value: {name:newName}})
patch(itemId, {value: {name:newName}})
12 Replies
ian
ian2y ago
We used to allow this but the behavior was too surprising. The way to do this (which won’t be any slower btw) is to do a db.get, then set the name, then do a db.replace
Gorka Cesium
Gorka CesiumOP2y ago
would it be a good idea if i change the schema to
items: defineTable(
v.object({
quote: v.id("quotes"),
tag: v.literal("ItemType1")
value: v.id("itemValue")
})
)
items: defineTable(
v.object({
quote: v.id("quotes"),
tag: v.literal("ItemType1")
value: v.id("itemValue")
})
)
? why would i need db.replace instead of spreading the old value and updating it with patch?
ian
ian2y ago
Spreading and using patch also works
Gorka Cesium
Gorka CesiumOP2y ago
patch(itemId, {value: {...oldValue, name:newName,}))
ian
ian2y ago
Yup that works too
Gorka Cesium
Gorka CesiumOP2y ago
what about value: v.id("itemValue") ? that would be patchable without get would that be inconvenient in some way?
ian
ian2y ago
You mean store the value in another table and just patch the id? That also works, you’d just need to do a db.get when you need to fetch it. For small bits of data with a 1:1 mapping I like to just nest the state but anything’s possible
Gorka Cesium
Gorka CesiumOP2y ago
ok i see, thanks i'm getting blocked because my schema is using unions of differente item types and each item type has a different value schema
defineTable(
v.union(
v.object({
quote: v.id("quotes"),
tag: v.literal("Complemento"),
value: v.object({
deliveryDaysOptimistic: v.number(), // int
name: v.string(),
reference: v.string(), // M01, M02, etc
}),
}),
v.object({
quote: v.id("quotes"),
tag: v.literal("PvcWindow"),
value: v.object({
heightMm: v.number(), // mm
price: v.number(), // float
}),
})
)
)
defineTable(
v.union(
v.object({
quote: v.id("quotes"),
tag: v.literal("Complemento"),
value: v.object({
deliveryDaysOptimistic: v.number(), // int
name: v.string(),
reference: v.string(), // M01, M02, etc
}),
}),
v.object({
quote: v.id("quotes"),
tag: v.literal("PvcWindow"),
value: v.object({
heightMm: v.number(), // mm
price: v.number(), // float
}),
})
)
)
so when i try to patch or replace it says that the argument of type tag: "PvcWindow"; value {... } is not assignable to parameter of type value (of Complmento)
let oldItem = await db.get(itemId);
if (!oldItem) throw new Error("item not found");

let value = {
...oldItem.value,
location,
heightMm,
widthMm,
};
const id = await db.replace(itemId, {
quote: oldItem.quote,
tag: "PvcWindow",
value,
});
return id;
let oldItem = await db.get(itemId);
if (!oldItem) throw new Error("item not found");

let value = {
...oldItem.value,
location,
heightMm,
widthMm,
};
const id = await db.replace(itemId, {
quote: oldItem.quote,
tag: "PvcWindow",
value,
});
return id;
attempt
Michal Srb
Michal Srb2y ago
Is it possible you’re spreading the “old” value that has fields that don’t belong with the new tag? You could destructure oldItem.value to get only the fields that should be carried over to the replaced/patched value.
Gorka Cesium
Gorka CesiumOP2y ago
yeah seems like there is a disconnect with the fields. The destructuring doesn't allow 3 fields that have unions themselves is there a special way to declare a variable that is a literal? i'm just doing a string
Michal Srb
Michal Srb2y ago
The destructuring doesn't allow 3 fields that have unions themselves
If these are TypeScript errors hopefully the typechecker is correct and indeed some variants of the union might not have those fields. Are you expecting oldItem to have the same tag PvcWindow? If yes you could assert that (via an if statement for example) and TypeScript should narrow the type of oldItem.
is there a special way to declare a variable that is a literal? i'm just doing a string
There should be nothing special about literals and variable declaration.
Gorka Cesium
Gorka CesiumOP2y ago
the if got rid of the TS error. the patch worked, thanks

Did you find this page helpful?