djbalin
djbalin2mo ago

Returning scheduled function id

Am I trippin or losing my mind - is is not possible to schedule an action in a mutation and return the scheduled function id? As soon as I attempt to return scheduledId in the function below, both the function declaration deleteUser and the scheduledId variable incur the TS error implicitly has type because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
export const deleteUser = authMutation({
returns: v.id('_scheduled_functions'),
handler: async (ctx) => {
const scheduledId = await ctx.scheduler.runAfter(0, api.act.testAction)
return scheduledId
},
})

// act.ts
export const testAction = action({
handler: async (ctx) => {
console.log('hey')
},
})
export const deleteUser = authMutation({
returns: v.id('_scheduled_functions'),
handler: async (ctx) => {
const scheduledId = await ctx.scheduler.runAfter(0, api.act.testAction)
return scheduledId
},
})

// act.ts
export const testAction = action({
handler: async (ctx) => {
console.log('hey')
},
})
4 Replies
djbalin
djbalinOP2mo ago
The logic works as intended if I just // @ts-ignore all the TS errors. What could cause this? I tried different permutations of file-function combinations, but didn't manage to find one that makes the error go away This breaks types and intellisense though, so not really viable
RJ
RJ2mo ago
See https://docs.convex.dev/functions/actions#dealing-with-circular-type-inference This comes up sometimes, but it’s easy to fix I believe you can also just annotate the return type of the action handler function And that way avoid needing to annotate every usage of it
djbalin
djbalinOP2mo ago
Ahh thanks @RJ , it put me on the right path. My problem was different: the outer mutation (which schedules an action) could not have its type inferred correctly. What simply fixed it was this, i.e. explicitly adding this type to the variable const scheduledId: Id<'_scheduled_functions'> = await ctx.scheduler.runAfter(.... Maybe that's what you meant. Thanks man!
// mutations.ts
export const deleteUser = authMutation({
handler: async (ctx) => {
const scheduledId: Id<'_scheduled_functions'> = await ctx.scheduler.runAfter(
1000 * 5,
internal.user.actions.deleteUserById,
{
userId: ctx.user._id,
clerkId: ctx.user.clerkId,
}
)

return scheduledId
},
})
// mutations.ts
export const deleteUser = authMutation({
handler: async (ctx) => {
const scheduledId: Id<'_scheduled_functions'> = await ctx.scheduler.runAfter(
1000 * 5,
internal.user.actions.deleteUserById,
{
userId: ctx.user._id,
clerkId: ctx.user.clerkId,
}
)

return scheduledId
},
})
RJ
RJ2mo ago
I meant this:
// act.ts
export const testAction = action({
- handler: async (ctx) => {
+ handler: async (ctx): void => {
console.log('hey')
},
})
// act.ts
export const testAction = action({
- handler: async (ctx) => {
+ handler: async (ctx): void => {
console.log('hey')
},
})
But glad you found a solution either way!

Did you find this page helpful?