Mathias
Mathias11mo ago

How to call a function within another function?

I would like to get an id from another function, instead of providing the id via args. My use case is that I want to get all users from a group using the current users activeGroupId. This query gives me the Id that I need:
export const getActiveSpace = internalQuery({
handler: async (ctx) => {
const identity = await ctx.auth.getUserIdentity()

if (!identity) {
throw new Error("Unauthenticated")
}

const userId = identity.subject

const user = await ctx.db
.query("users")
.withIndex("by_user", (q) => q.eq("userId", userId))
.first()

if (!user) {
throw new Error("Not found")
}

return user.activeSpace
},
})
export const getActiveSpace = internalQuery({
handler: async (ctx) => {
const identity = await ctx.auth.getUserIdentity()

if (!identity) {
throw new Error("Unauthenticated")
}

const userId = identity.subject

const user = await ctx.db
.query("users")
.withIndex("by_user", (q) => q.eq("userId", userId))
.first()

if (!user) {
throw new Error("Not found")
}

return user.activeSpace
},
})
Now, I don't know how to use it in my query to get all members. This is the current code, where the groupId is an empty string, which is the one I want to get replaced by the output of getActiveSpace:
export const getGroupMembers = query({
handler: async (ctx) => {
const identity = await ctx.auth.getUserIdentity()

if (!identity) {
throw new Error("Unauthenticated")
}

const groupId = ""

const groupMembers = await ctx.db
.query("groupMembers")
.withIndex("by_groupId", (q) => q.eq("groupId", groupId))
.collect()

const userIds = groupMembers.map((member) => member.userId)

const users = await Promise.all(
userIds.map((id) => ctx.db.get(id as Id<"users">))
)

return users.filter((user) => user !== null)
},
})
export const getGroupMembers = query({
handler: async (ctx) => {
const identity = await ctx.auth.getUserIdentity()

if (!identity) {
throw new Error("Unauthenticated")
}

const groupId = ""

const groupMembers = await ctx.db
.query("groupMembers")
.withIndex("by_groupId", (q) => q.eq("groupId", groupId))
.collect()

const userIds = groupMembers.map((member) => member.userId)

const users = await Promise.all(
userIds.map((id) => ctx.db.get(id as Id<"users">))
)

return users.filter((user) => user !== null)
},
})
Can you point me in towards a ressource or help me what I missed to get it to work? There might also be a simpler solution.
4 Replies
erquhart
erquhart11mo ago
You can’t call a query from another query - if you ever need to, you can instead split out the code inside of the function you want to reuse so you can reuse it in multiple queries. In this case, you could create a regular function that is used by both getActiveSpace and getGroupMembers queries. All of that said, the code in your getActiveSpace query is so straightforward, I would just write the user query in both of your query functions.
Mathias
MathiasOP11mo ago
Okay thank you! I tend to overcomplicate things as I often think that it will effect the performance, but Convex handles everything really well!
erquhart
erquhart11mo ago
For sure. Premature optimization is an even greater temptation than usual with Convex in my experience, it’s faster than you’d expect. I’ve learned to just get things working and go back to see what needs improving.
Mathias
MathiasOP11mo ago
That is a good approach. Thanks for the advice. I'll get cracking with the app. 🙂

Did you find this page helpful?