Having to put v.optional in the schema file
So i have a function that first inserts a document in one table, and i use that id when i insert into another table because they are related data. but i am having to put v.optional(v.id('invoicelist')) why is that i want to make sure that this field is not optinal and there will always be a v.id of invoice list in it.
8 Replies
Sounds like you've got a circular reference. What you're doing sounds similar to what we're doing in our docs: https://docs.convex.dev/database/schemas#circular-references
This is a known limitation of the system today.
Schemas | Convex Developer Hub
Schema validation keeps your Convex data neat and tidy. It also gives you end-to-end TypeScript type safety!
If it's not circular, it's possible it could just take some TypeScript finesse. If this is the case, can you share the code you're using to insert the two documents?
import { mutation } from './_generated/server';
import { v } from 'convex/values';
export const addNewInvoice = mutation({
args: {
advance: v.number(),
balance: v.number(),
customerAddress: v.string(),
customerEmail: v.string(),
customerName: v.string(),
customerPhone: v.string(),
discount: v.number(),
invoiceDate: v.string(),
total: v.number(),
invoiceNo: v.number(),
itemRows: v.array(
v.object({
invoiceItemRow: v.number(),
itemName: v.string(),
itemPrice: v.number(),
itemQty: v.number(),
subTotal: v.number(),
}),
),
},
handler: async (ctx, args) => {
const newInvoiceId = await ctx.db.insert('invoiceList', {
advance: args.advance,
balance: args.balance,
customerAddress: args.customerAddress,
customerEmail: args.customerEmail,
customerName: args.customerName,
customerPhone: args.customerPhone,
discount: args.discount,
invoiceDate: args.invoiceDate,
total: args.total,
invoiceNo: args.invoiceNo,
});
for (let i = 0; i < args.itemRows.length; i++) {
const row = args.itemRows[i];
const SalesSpecId = await ctx.db.insert('salesSpecification', {
itemName: row.itemName,
qty: row.itemQty,
rowNo: row.invoiceItemRow,
subTotal: row.subTotal,
unitPrice: row.itemPrice,
invoiceId: newInvoiceId,
});
}
return typeof newInvoiceId;
},
});
This is my code, there was error i was getting null until i changed the schma of my salesspecification table to v.optional(v.id())
Is this an example of the circular error, i only need the salesSpecification to hold the invoiceNo i don't need to store the sales spec Id in Invoice List TableNo this does not seem circular. Was the error a type error or an error during deployment? Or was it returning invalid data? The code looks fine.
If you have any
salesSpecification
s in your database where invoiceId
isn't set, it would have prevented you from deploying the schema, since it wouldn't have matched all the existing data.
btw you could avoid some duplication by changing this line:
to
And then doing
And if you pull the definition of the invoice fields out of defineSchema to reuse, you could potentially make the validator something like {...invoiceFields, itemRows: ...}
if that makes sense?
It should work as-written too, just mentioning those patterns in case they're helpful to you ✌️import { defineSchema, defineTable } from 'convex/server';
import { v } from 'convex/values';
export default defineSchema({
invoiceList: defineTable({
invoiceNo: v.number(),
invoiceDate: v.string(),
customerName: v.string(),
customerAddress: v.string(),
customerEmail: v.string(),
customerPhone: v.string(),
total: v.number(),
discount: v.number(),
advance: v.number(),
balance: v.number(),
}),
salesSpecification: defineTable({
rowNo: v.number(),
invoiceId: v.optional(v.id('invoiceList')),
itemName: v.string(),
unitPrice: v.number(),
qty: v.number(),
subTotal: v.number(),
}),
itemList: defineTable({
itemName: v.string(),
itemCode: v.string(),
dollarPrice: v.number(),
}),
customerList: defineTable({
customerName: v.string(),
customerAddress: v.string(),
customerEmail: v.string(),
customerPhone: v.string(),
}),
appState: defineTable({
dollarRate: v.number(),
}),
});
This is my schema.ts file
in the salesSpecifrication table if i dont put v.optional it shows error in the console when i do npx convex dev
so i tried returning the invoiceID from the function it returns null, but when i put v.optional it all works
This is the error in my console
when i remove the v.optional
IDK what happened, but it is working now, thanks alot for the tip about the destructuring i will try to look out for more of those in the future
definetly impoved my code repairability
I think i found the issue, i had previous data existing in the table which was messing with my schmea
I deleted all the data and it works
Glad to hear it! And so we can improve, I think the issue here was that the error about data in your database gave you the impression it was an issue with your schema. Adding optional "fixed" it by allowing the data in the database to continue existing, but you didn't want it to be optional. To remove optional you had to update the data to match the desired schema (in this case delete the data) in order for the push to succeed.