Deleting a Project
Deleting a Project
~12 Min. Lesezeit Zuletzt aktualisiert am August 8, 2026
Deleting is IRREVERSIBLE (chapter 44: cascade: ['remove'] ALSO deletes all tasks) – a confirmation dialog is ESPECIALLY important HERE.
Writing the delete hook
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { apiClient } from '../api/client';
export function useDeleteProject() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (id: number) => {
await apiClient.delete(`/projects/${id}`);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['projects'] });
},
});
}EXACTLY as chapter 10 showed: DELETE returns 204 No Content, NO response body – mutationFn correspondingly returns NOTHING (Promise<void>).
A confirmation dialog
function DeleteProjectButton({ projectId }: { projectId: number }) {
const deleteProject = useDeleteProject();
function handleClick() {
const confirmed = window.confirm(
'Really delete this project? All related tasks will also be deleted.',
);
if (confirmed) {
deleteProject.mutate(projectId);
}
}
return (
<button onClick={handleClick} disabled={deleteProject.isPending}>
Delete
</button>
);
}Achtung: window.confirm is the SIMPLEST solution, but blocks the ENTIRE browser tab and can NOT be styled – for a PRODUCTION-READY UI, a CUSTOM modal component would be the BETTER choice. For OUR learning project, the native dialog is COMPLETELY sufficient.
Handling 403 correctly
The voter from chapters 52-53 can REJECT a deletion with 403 (e.g. if the deleter is NOT the owner) – the GLOBAL 401 interceptor from chapter 77 does NOT kick in HERE (403 is NOT an authentication error), but the hook's isError is ENOUGH to show a matching message.
Tipp: EXACTLY as chapter 53 introduced securityMessage for server-side error messages, the frontend can read error.response?.data."hydra:description" to show THIS message DIRECTLY in the UI, instead of inventing a CUSTOM, generic error message.