Rune Darkfire
Rune Darkfire
CCConvex Community
Created by Rune Darkfire on 9/28/2024 in #support-community
Can't deploy convex to production with vercel correctly.
As per title. Been following this guide here, it's fairly clear : https://docs.convex.dev/production/hosting/vercel. All the steps seem to have been completed fine, and then when I goto my convex dashboard and make sure I am on the production instance of my app, I can see that my tables exist in the DB, but once logged in to my deployed appication, I can't actually populate any data. I'm aware this is a very vague question but I'm not sure how to provide any more details. My code all works perfectly fine locally and the database integration locally has been fine, I have a fully functional application. But I'm just not sure where to go from here. It appears the database calls just aren't doing anything at all on my production environment -- looking in dev tools in Chrome, I don't see any activity at all when I click on a button that should generate activity. Any help would be appreciated - thank you!
33 replies
CCConvex Community
Created by Rune Darkfire on 9/25/2024 in #support-community
Can't correctly type fields from a table to my NextTS application
This is more of a pure TS question than Convex, but at least it originates from the types of one of my convex function definitions. I'm getting this type error when trying to build my project (been fixing them by the dozens as we get ready for deployment) :
Type error: Type 'ReactMutation<FunctionReference<"mutation", "public", { id: Id<"documents">; orgId: string | null; storageId: Id<"_storage">; }, null, string | undefined>>' is not assignable to type '(params: { id: XOR<Id<"documents">, Id<"vendors">, Id<"contracts">, Id<"riskAssessments">>; orgId?: string | null | undefined; storageId?: string | undefined; }) => Promise<...>'.
Types of parameters 'args' and 'params' are incompatible.
Type '{ id: XOR<Id<"documents">, Id<"vendors">, Id<"contracts">, Id<"riskAssessments">>; orgId?: string | null | undefined; storageId?: string | undefined; }' is not assignable to type '{ id: Id<"documents">; orgId: string | null; storageId: Id<"_storage">; }'.
Types of property 'id' are incompatible.
Type 'XOR<Id<"documents">, Id<"vendors">, Id<"contracts">, Id<"riskAssessments">>' is not assignable to type 'Id<"documents">'.
Type '{ [x: string]: undefined; [x: symbol]: undefined; readonly [x: number]: string; toString: () => string; charAt: (pos: number) => string; charCodeAt: (index: number) => number; concat: (...strings: string[]) => string; ... 48 more ...; __tableName: "documents"; }' is not assignable to type 'Id<"documents">'.
Type '{ [x: string]: undefined; [x: symbol]: undefined; readonly [x: number]: string; toString: () => string; charAt: (pos: number) => string; charCodeAt: (index: number) => number; concat: (...strings: string[]) => string; ... 48 more ...; __tableName: "documents"; }' is not assignable to type 'string'.
Type error: Type 'ReactMutation<FunctionReference<"mutation", "public", { id: Id<"documents">; orgId: string | null; storageId: Id<"_storage">; }, null, string | undefined>>' is not assignable to type '(params: { id: XOR<Id<"documents">, Id<"vendors">, Id<"contracts">, Id<"riskAssessments">>; orgId?: string | null | undefined; storageId?: string | undefined; }) => Promise<...>'.
Types of parameters 'args' and 'params' are incompatible.
Type '{ id: XOR<Id<"documents">, Id<"vendors">, Id<"contracts">, Id<"riskAssessments">>; orgId?: string | null | undefined; storageId?: string | undefined; }' is not assignable to type '{ id: Id<"documents">; orgId: string | null; storageId: Id<"_storage">; }'.
Types of property 'id' are incompatible.
Type 'XOR<Id<"documents">, Id<"vendors">, Id<"contracts">, Id<"riskAssessments">>' is not assignable to type 'Id<"documents">'.
Type '{ [x: string]: undefined; [x: symbol]: undefined; readonly [x: number]: string; toString: () => string; charAt: (pos: number) => string; charCodeAt: (index: number) => number; concat: (...strings: string[]) => string; ... 48 more ...; __tableName: "documents"; }' is not assignable to type 'Id<"documents">'.
Type '{ [x: string]: undefined; [x: symbol]: undefined; readonly [x: number]: string; toString: () => string; charAt: (pos: number) => string; charCodeAt: (index: number) => number; concat: (...strings: string[]) => string; ... 48 more ...; __tableName: "documents"; }' is not assignable to type 'string'.
Now obviously that is a huge mouthful.
12 replies
CCConvex Community
Created by Rune Darkfire on 9/19/2024 in #support-community
How do I wait for a useQuery declaration to return before proceeding?
I feel like I'm missing something simple. Here's the code for a component that gets called on many pages in my application :
const { isLoaded, isSignedIn, orgId } = useAuth();

const contractTypes = useQuery(api.contract_types.list, { orgId: orgId !== undefined ? orgId : undefined }) || []
const addContractType = useMutation(api.contract_types.add)
const vendorCategories = useQuery(api.vendor_categories.list, { orgId: orgId !== undefined ? orgId : undefined }) || []
const addVendorCategory = useMutation(api.vendor_categories.add)

const settingsLoaderRef = useRef(false);

useEffect(() => {
if (!settingsLoaderRef.current && isLoaded && isSignedIn && orgId
&& contractTypes && vendorCategories) {
settingsLoaderRef.current = true // EXECUTION GETS HERE BUT contractTypes AND vendorCategories are returning the empty array, even though I know they should have data in them
if (!contractTypes.length) setContractTypeDefaults()
if (!vendorCategories.length) setVendorCategoryDefaults()
}
}, [isLoaded, isSignedIn, contractTypes, vendorCategories, orgId]);
const { isLoaded, isSignedIn, orgId } = useAuth();

const contractTypes = useQuery(api.contract_types.list, { orgId: orgId !== undefined ? orgId : undefined }) || []
const addContractType = useMutation(api.contract_types.add)
const vendorCategories = useQuery(api.vendor_categories.list, { orgId: orgId !== undefined ? orgId : undefined }) || []
const addVendorCategory = useMutation(api.vendor_categories.add)

const settingsLoaderRef = useRef(false);

useEffect(() => {
if (!settingsLoaderRef.current && isLoaded && isSignedIn && orgId
&& contractTypes && vendorCategories) {
settingsLoaderRef.current = true // EXECUTION GETS HERE BUT contractTypes AND vendorCategories are returning the empty array, even though I know they should have data in them
if (!contractTypes.length) setContractTypeDefaults()
if (!vendorCategories.length) setVendorCategoryDefaults()
}
}, [isLoaded, isSignedIn, contractTypes, vendorCategories, orgId]);
How can I make this useEffect do what I want so that the vendorCategories and contractTypes tables in the DB don't keep adding the defaults over & over? To be clear -- the very first time this code is called after a login, it behaves as if the arrays are empty, but when I navigate away from any pages with this component and then come back, it recognizes what's in the DB at that point. How do I make sure it loads what's in the DB from the useQuery the FIRST time this is called after login?
6 replies
CCConvex Community
Created by Rune Darkfire on 9/17/2024 in #support-community
OrganizationSwitcher from clerk not propogating org_id to convex getUserIdentity call
Perhaps I'm misunderstanding this technology, but I thought that you could use the OrganizationSwitcher component in clerk (assuming the org_id claim is set up in the jwt settings) to "tell" the user called from the getUserIdentity call in convex which org it is on (https://clerk.com/docs/components/organization/organization-switcher). That way, I don't have to deal with messy / arbitrary passing of orgIds & userIds from the front-end. Is there actually a correct way to do this?
5 replies
CCConvex Community
Created by Rune Darkfire on 9/16/2024 in #support-community
Getting orgId from userIdentity does not work
I can't seem to apply my org ID to newly created resources. I'm not sure what I'm doing wrong :
export const add = mutation({
args: {
orgId: v.optional(v.string()),
name: v.string(),
category: v.string(),
contactPerson: v.string(),
email: v.string(),
phone: v.string(),
address: v.string(),
website: v.string(),
description: v.string(),
status: v.string(),
riskScore: v.optional(v.number()),
totalSpend: v.optional(v.number()),
performance: v.optional(v.number()),
logoStorageId: v.optional(v.id("_storage")),
},
handler: async (ctx, args) => {
const user = await ctx.auth.getUserIdentity()

if (user === null) {
return null
}

const vendorId = await ctx.db.insert("vendors", {
...args,
orgId: user.orgId,
createdAt: Date.now(),
updatedAt: Date.now(),
})
return vendorId
},
})
export const add = mutation({
args: {
orgId: v.optional(v.string()),
name: v.string(),
category: v.string(),
contactPerson: v.string(),
email: v.string(),
phone: v.string(),
address: v.string(),
website: v.string(),
description: v.string(),
status: v.string(),
riskScore: v.optional(v.number()),
totalSpend: v.optional(v.number()),
performance: v.optional(v.number()),
logoStorageId: v.optional(v.id("_storage")),
},
handler: async (ctx, args) => {
const user = await ctx.auth.getUserIdentity()

if (user === null) {
return null
}

const vendorId = await ctx.db.insert("vendors", {
...args,
orgId: user.orgId,
createdAt: Date.now(),
updatedAt: Date.now(),
})
return vendorId
},
})
I have tried all manner of permutations of the orgId field above but it always results in an error either to do with not matching the schema (for the one above), or simply argument validation error with "Object is missing the required field 'orgId'" if I remove the optional, or remove the entry from the args altogether. I have added the claim for org ID in the JWT template that I'm using :
"org_id": "{{org.id}}"
"org_id": "{{org.id}}"
and it has saved/persisted in my Clerk config. From the guides I've read, this seems how I should be able to retrieve the org ID, but obviously something's wrong -- any help would be appreciated, thank you.
5 replies
CCConvex Community
Created by Rune Darkfire on 9/16/2024 in #support-community
Optional validator in mutation not working for one attribute but fine for others
I'm not sure what I'm doing wrong on this mutation, I consistently get an error on the logoStorageId when I am calling it when the value is null. None of the other optional validators are giving me grief, just this one :
export const update = mutation({
args: {
id: v.id("vendors"),
name: v.optional(v.string()),
category: v.optional(v.string()),
contactPerson: v.optional(v.string()),
email: v.optional(v.string()),
phone: v.optional(v.string()),
address: v.optional(v.string()),
website: v.optional(v.string()),
description: v.optional(v.string()),
status: v.optional(v.string()),
riskScore: v.optional(v.number()),
totalSpend: v.optional(v.number()),
performance: v.optional(v.number()),
logoStorageId: v.optional(v.id("_storage")),
},
handler: async (ctx, args) => {
const { id, ...fields } = args

if (args.logoStorageId) {
const vendor = await ctx.db.get(args.id);

if (vendor?.logoStorageId) {
await ctx.storage.delete(vendor.logoStorageId)
}
}
await ctx.db.patch(id, {
...fields,
updatedAt: Date.now(),
})
},
})
export const update = mutation({
args: {
id: v.id("vendors"),
name: v.optional(v.string()),
category: v.optional(v.string()),
contactPerson: v.optional(v.string()),
email: v.optional(v.string()),
phone: v.optional(v.string()),
address: v.optional(v.string()),
website: v.optional(v.string()),
description: v.optional(v.string()),
status: v.optional(v.string()),
riskScore: v.optional(v.number()),
totalSpend: v.optional(v.number()),
performance: v.optional(v.number()),
logoStorageId: v.optional(v.id("_storage")),
},
handler: async (ctx, args) => {
const { id, ...fields } = args

if (args.logoStorageId) {
const vendor = await ctx.db.get(args.id);

if (vendor?.logoStorageId) {
await ctx.storage.delete(vendor.logoStorageId)
}
}
await ctx.db.patch(id, {
...fields,
updatedAt: Date.now(),
})
},
})
This is the error, it's behaving as if it's not optional for some reason :
[CONVEX M(vendors:update)] [Request ID: f176b6cccf8b730e] Server Error
ArgumentValidationError: Value does not match validator.
Path: .logoStorageId
Value: null
Validator: v.id("_storage")
[CONVEX M(vendors:update)] [Request ID: f176b6cccf8b730e] Server Error
ArgumentValidationError: Value does not match validator.
Path: .logoStorageId
Value: null
Validator: v.id("_storage")
Because there's no way to actually step through this code (is there??) I can't actually see where precisely it is going wrong. Any help would be appreciated - thank you!
3 replies
CCConvex Community
Created by Rune Darkfire on 9/10/2024 in #support-community
How to return a custom list with extra key-value pair(s)?
I am trying to return list from my table "riskAssessments" but with an extra key-value pair on each element to add in the value of a subquery :
export const listWithVendorNames = query({
handler: async (ctx) => {
const assessments = await ctx.db.query("riskAssessments").collect()
let assessmentsWithVendorNames = []

assessments.forEach(async (assessment) => {
assessmentsWithVendorNames.push({ ...assessment, vendorName: await getVendorName(ctx, assessment.vendorId ?? null) })
})
return assessmentsWithVendorNames
},
})

...

async function getVendorName(ctx: QueryCtx, vendorId: Id<"vendors"> | null) {
if (vendorId === null) {
return null
}
return (await ctx.db.get(vendorId))?.name;
}
export const listWithVendorNames = query({
handler: async (ctx) => {
const assessments = await ctx.db.query("riskAssessments").collect()
let assessmentsWithVendorNames = []

assessments.forEach(async (assessment) => {
assessmentsWithVendorNames.push({ ...assessment, vendorName: await getVendorName(ctx, assessment.vendorId ?? null) })
})
return assessmentsWithVendorNames
},
})

...

async function getVendorName(ctx: QueryCtx, vendorId: Id<"vendors"> | null) {
if (vendorId === null) {
return null
}
return (await ctx.db.get(vendorId))?.name;
}
I know that the subquery works because I use it in my getById query which returns a single entry. The basic list query I've defined also returns the correct result. Because there's no way (seemingly?) to step through the .ts file code on my browser dev-tools, I have no idea where it is going wrong, but it is simply returning an empty array instead of what I want. I'm sorry if this is the wrong place to put this question - this is the only place I've been able to find. Thanks for reading! EDIT : I had to add the --typecheck=disable flag to get convex to run, as I'm using TS.
6 replies