
Join the Conversation!
Subscribing gives you access to the comments so you can share your ideas, ask questions, and connect with others.
"Please login to view comments"
Subscribing gives you access to the comments so you can share your ideas, ask questions, and connect with others.
You’re almost there.
Just like you did with deleting questions, it’s time to implement the delete functionality for answers. Yes — it’s a bit of repetition, but you know the drill by now.
Start with the usual setup (you probably don’t even need to pause to think about it at this point)
Define type for params
interface DeleteAnswerParams {
answerId: string;
}
Create validation schema for params
export const DeleteAnswerSchema = z.object({
answerId: z.string().min(1, "Answer ID is required"),
});
Write the initial skeleton for your new server action inside lib/actions/answer.action.ts
export async function deleteAnswer(
params: DeleteAnswerParams
): Promise<ActionResponse> {
const validationResult = await action({
params,
schema: DeleteAnswerSchema,
authorize: true,
});
if (validationResult instanceof Error) {
return handleError(validationResult) as ErrorResponse;
}
const { answerId } = validationResult.params!;
const { user } = validationResult.session!;
try {
// implement logic here
return { success: true };
} catch (error) {
return handleError(error) as ErrorResponse;
}
}
Everything should feel like second nature by now. But don’t skip the logic — it’s just as important.
Here’s what you’ll need to handle when deleting an answer:
And just like with question deletion — remember to use a Mongoose session to keep everything atomic. All changes should happen together or not at all.
You’ve got this 💪
Are you ready to check out the final solution?
export async function deleteAnswer(
params: DeleteAnswerParams
): Promise<ActionResponse> {
const validationResult = await action({
params,
schema: DeleteAnswerSchema,
authorize: true,
});
if (validationResult instanceof Error) {
return handleError(validationResult) as ErrorResponse;
}
const { answerId } = validationResult.params!;
const { user } = validationResult.session!;
try {
const answer = await Answer.findById(answerId);
if (!answer) throw new Error("Answer not found");
if (answer.author.toString() !== user?.id)
throw new Error("You're not allowed to delete this answer");
// reduce the question answers count
await Question.findByIdAndUpdate(
answer.question,
{ $inc: { answers: -1 } },
{ new: true }
);
// delete votes associated with answer
await Vote.deleteMany({ actionId: answerId, actionType: "answer" });
// delete the answer
await Answer.findByIdAndDelete(answerId);
revalidatePath(`/profile/${user?.id}`);
return { success: true };
} catch (error) {
return handleError(error) as ErrorResponse;
}
}
Nothing too wild here — way simpler than deleting a question. Nice and easy.
Now it’s your turn. Plug this server action into the EditDeleteAction component and give it a go
"use client";
import ...
import { deleteAnswer } from "@/lib/actions/answer.action";
interface Props {...}
const EditDeleteAction = ({ type, itemId }: Props) => {
const router = useRouter();
const handleEdit = async () => {...};
const handleDelete = async () => {
if (type === "Question") {
...
} else if (type === "Answer") {
await deleteAnswer({ answerId: itemId });
toast({
title: "Answer Deleted",
variant: "destructive",
description: "Your answer has been successfully deleted.",
});
}
};
return (
<div className="flex items-center justify-end gap-3 max-sm:w-full">
...
</div>
);
};
export default EditDeleteAction;
All set. Go and put it through a good stress test.
Complete source code for this lesson is available at
How did you manage to remove the blur property and reach here?
Upgrading gives you access to quizzes so you can test your knowledge, track progress, and improve your skills.