NanaGaisie
NanaGaisie15mo ago

Using Action

Hey, I am new to convex. I have written a mutation function for my application. The function needs to call an API to get the user ID of an individual. I get this error when I save my file. error: archive defined in documents.js is a Mutation function. Only actions can be defined in Node.js. I am not familiar with actions. Can someone help me?
export const archive = mutation({
args: { id: v.id("documents") },
handler: async (ctx, args) => {
const response = await fetch("http://localhost:3000/api/auth/kindeSession");
if (!response.ok) {
throw new Error("Failed to fetch user data");
}
const data = await response.json();
const usersId = data.user.id; // Extract the 'userId' from the response

const identity = usersId;

if (!identity) {
throw new Error("Not authenticated");
}

const userId = await identity;

const existingDocument = await ctx.db.get(args.id);

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

if (existingDocument.userId !== userId) {
throw new Error("Unauthorized");
}

const recursiveArchive = async (documentId: Id<"documents">) => {
const children = await ctx.db
.query("documents")
.withIndex("by_user_parent", (q) =>
q.eq("userId", userId).eq("parentDocument", documentId),
)
.collect();

for (const child of children) {
await ctx.db.patch(child._id, {
isArchived: true,
});

await recursiveArchive(child._id);
}
};

const document = await ctx.db.patch(args.id, {
isArchived: true,
});

recursiveArchive(args.id);

return document;
},
});
export const archive = mutation({
args: { id: v.id("documents") },
handler: async (ctx, args) => {
const response = await fetch("http://localhost:3000/api/auth/kindeSession");
if (!response.ok) {
throw new Error("Failed to fetch user data");
}
const data = await response.json();
const usersId = data.user.id; // Extract the 'userId' from the response

const identity = usersId;

if (!identity) {
throw new Error("Not authenticated");
}

const userId = await identity;

const existingDocument = await ctx.db.get(args.id);

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

if (existingDocument.userId !== userId) {
throw new Error("Unauthorized");
}

const recursiveArchive = async (documentId: Id<"documents">) => {
const children = await ctx.db
.query("documents")
.withIndex("by_user_parent", (q) =>
q.eq("userId", userId).eq("parentDocument", documentId),
)
.collect();

for (const child of children) {
await ctx.db.patch(child._id, {
isArchived: true,
});

await recursiveArchive(child._id);
}
};

const document = await ctx.db.patch(args.id, {
isArchived: true,
});

recursiveArchive(args.id);

return document;
},
});
2 Replies
Omar Farooq
Omar Farooq15mo ago
@NanaGaisie Since you're calling a 3rd party API you'd want to use an Action for that part: https://docs.convex.dev/functions/actions And you can write the Mutation inside of the Action as the subsequent step.
Actions | Convex Developer Hub
Actions can call third party services to do things such as processing a payment
Michal Srb
Michal Srb15mo ago
Hey @NanaGaisie, remove “use node” from the file, or move the mutation to another file. Like Omar said fetch can only be called from an action. Also note that the function always runs in the cloud, so you cannot call endpoints on localhost - you’d need to use a deployed server, or move the logic from kindeSession into a Convex function.

Did you find this page helpful?