Skip to main content

Delete Task and Shadcn Vue Toast Notification

Premium
4 min read

In this lesson, let's add the Delete button to our table.


Delete Button

Here's what we have in the Controller:

app/Http/Controllers/TaskController.php:

public function destroy(Task $task)
{
$task->delete();
 
return redirect()->route('tasks.index');
}

Since we have Route::resource() here, the Vue component should fire a DELETE request to the route /tasks/{ID}.

So, first, we define the function inside the Vue component.

resources/js/pages/Tasks/Index.vue:

import { Head } from '@inertiajs/vue3';
import { Head, router } from '@inertiajs/vue3';
 
// ...
 
defineProps<Props>();
 
const deleteTask = (id: number) => {
if (confirm('Are you sure you want to delete this task?')) {
router.delete(route('tasks.destroy', { id }));
}
};
 
// ...

Then, we need to add a Button to the table that calls the deleteTask() method.

The Shadcn Button component is already installed in the starter kit, so we don't need to run any npx commands. We just need to import it with button variants.

We add a new <TableCell> to...

The Full Lesson is Only for Premium Members

Want to access all of our courses? (36 h 00 min)

You also get:

61 courses
Premium tutorials
Access to repositories
Private Discord
Get Premium for $129/year or $29/month

Already a member? Login here

Richard A. Hoyle avatar

the GitHub link is not working

Povilas Korop avatar

Sorry, sometimes I forget to put repositories public. Fixed now!

Paweł Liszka avatar

the main problem here is if backend breakes or network go donw we still have positive info about "delete success" even the item is never deleated

Modestas avatar

Indeed. That's a separate case that should be handled. For example, if the API did not work - the success message and item state should not change.

Alexandre avatar

You could use one or more Event Callbacks from Inertia.js and make small changes to deleteTask. This is one possible solution:

// ...
const deleteTask = (id: number) => {
if (confirm('Are you sure you want to delete this task?')) {
router.delete(route('tasks.destroy', { id }), {
onSuccess: () => {
toast(`Task #${id} has been deleted.`);
}
});
}
};
// ...

How to test this code? On the development machine:

  • To test the happy path "task deleted", do it normally;
  • To test the sad path. After navigating to the Tasks page, bring down the server, then press the "delete" button".
Modestas avatar

Thanks, I updated the article with this!

Alexandre avatar

Either there is a new Sonner version or you may have forgotten to add one line into the file resources/js/layouts/app/AppHeaderLayout.vue. That line is needed for styling, including the positioning of the component. So, the code will be:

// ...
 
import { Toaster } from '@/components/ui/sonner';
import 'vue-sonner/style.css'; // add this line
 
// ...

Source: Sonner; Installation; then #2.

Modestas avatar

I'm pretty sure that there was an update with the package, since in the demo code (written for the course) - everything works as expected (including styling)

Modestas avatar

Updated the lesson with this :)

We originally had 1.3 version of vue-sonner, and they released 2.0 with new structure.

Taffo Velikoff avatar

Do I need some sort of a package installed to use roure()?
router.delete(route('tasks.destroy', { id }));

Modestas avatar

It should be working out of the box, unless they released some new update to the starter kits

Taffo Velikoff avatar

Yeah seems they did. I had to install Ziggy myself..

d8bd8b avatar

Now Starter Kits have wayfinder installed.

Usage:

CLI:

php artisan wayfinder:generate

resources/js/pages/Tasks/Index.vue:

import { destroy } from '@/actions/App/Http/Controllers/TaskController';
 
const deleteTask = (id: number) => {
if (confirm('Are you sure you want to delete this task?')) {
router.delete(destroy.url(id), {
onSuccess: () => toast.success('Task deleted successfully'),
onError: () => toast.error('Failed to delete task'),
});
}
};

We'd Love Your Feedback

Tell us what you like or what we can improve

Feel free to share anything you like or dislike about this page or the platform in general.