@danny971 Hey, Try this
<a style ="cursor:pointer;" wire:click.prevent="deleteProduct({{ $product}})" class="delete" ><i class="bi bi-trash red mr-1"></i></a>
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
im new to Livewire. I was following a tutorial but got stuck . Im trying to delete a product from my database with the following code
The html
@foreach($category->products as $product)
<li class="list-group-item d-flex justify-content-between align-items-center">{{ $product->product_name }}
<div class="btn-group">
<a style ="cursor:pointer;" wire:click="deleteProduct({{ $product}})" class="delete" ><i class="bi bi-trash red mr-1"></i></a>
</div>
</li>
@endforeach
the livewire code
namespace App\Http\Livewire;
use Livewire\Component;
use App\Models\Products;
use Illuminate\Support\Facades\DB;
class DeleteProduct extends Component
{
public $productId; // Store the product ID for deletion
protected $listeners = ['confirmDelete'];
public function render()
{
return view('livewire.delete-product');
}
public function deleteProduct(Product $product) {
$product -> delete();
session()->flash('notification', ['type' => 'success', 'message' => 'Product deleted successfully']);
$this -> emit('productDeleted');
}
}
what am i doing wrong or missing. when i click the link tag nothing happens
@danny971 Hey, Try this
<a style ="cursor:pointer;" wire:click.prevent="deleteProduct({{ $product}})" class="delete" ><i class="bi bi-trash red mr-1"></i></a>
@amitsolanki24_ already did tried it with the wire.click.prevent. it didn't work
You're using v2 or v3?
@lucasweaver v2.12.6
Try refactoring like this:
<button wire:click="deleteProduct({{ $product->id }})">Delete</button>
public function deleteProduct($productId)
{
$product = Product::find($productId);
if ($product) {
$product->delete();
}
}
@lucasweaver thanks for helping me out but i figured it out. im now trying to figureout why the list isnt reloading when i delete an Item . I tried the mount function no luck
@lucasweaver can you help me figure out why my products isnt refreshing in the case of live wire update after a product is deleted the mount function is supposed to take care of that , right ?
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use App\Models\Products;
use Illuminate\Support\Facades\DB;
class DeleteProduct extends Component
{
public $productId;
public function mount() {
$this->products = Products::all();
}
public function render()
{
return view('livewire.delete-product');
}
public function deleteProduct(Products $products) {
$products -> delete();
$this -> mount();
/* $product = Products::find($this->productId);
if ($product) {
$product->delete();
session()->flash('notification', ['type' => 'success', 'message' => 'Product deleted successfully']);
$this->emit('productDeleted');
$this-> mount();
} */
}
}
I would declare $products as public and then reset:
$this->products = Products::all(); in the delete products or in separate function
@lucasweaver could you explain better or with code example
@Danny971 Something like this:
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use App\Models\Products;
use Illuminate\Support\Facades\DB;
class DeleteProduct extends Component
{
public $productId;
public $products;
public function mount()
{
$this->getProducts();
}
public function getProducts()
{
$this->products = Products::all();
}
public function deleteProduct(Products $products)
{
$products->delete();
$this->getProducts();
$this->emit('productDeleted');
}
public function render()
{
return view('livewire.delete-product');
}
}
mount only runs once on page load.
You should fetch your products in the render and pass it to the view as you would in a traditional controller. DO NOT create a public property for it as the whole of the models table will be shared with the front end on every request.
@Snapey your statement " You should fetch your products in the render and pass it to the view as you would in a traditional controller." I tried that already and no luck
public function render()
{
return view('livewire.delete-product', [
'products' => $this->products,
]);
But before that, where in your view do you load this livewire component?
@Snapey this is it
<livewire:delete-product :product-id="$product->id" :key="$product->id" />
here is the full code
<div class="col-md-9">
<div class="tab-content">
@foreach ($categories as $category)
<div id="category-{{ $category->id }}" class="tab-pane fade">
<ul class="list-group">
<li class="list-group-item active d-flex justify-content-between align-items-center">
{{ $category->category_name }}
<div class="btn-group">
<a href="#" class="delete" data-product-id="{{ $category->id }}" data-target=""><i class="bi bi-trash text-white mr-4"></i></a>
<a href="#" class="edit" data-target=""><i class="bi bi-pencil-fill text-white mr-4"></i></a>
<a href="#" class="add" data-target=""><i class="bi bi-plus-lg text-white"></i></a>
</div>
</li>
@if ($category->products->isNotEmpty())
@foreach($category->products as $product)
<li class="list-group-item d-flex justify-content-between align-items-center">{{ $product->product_name }}
<div class="btn-group">
<livewire:delete-product :product-id="$product->id" :key="$product->id" />
<!-- <a href="#" class="delete" data-product-id="{{ $product->id }}"><i class="bi bi-trash red mr-1"></i></a> -->
<a href="#" class="edit" data-toggle="modal" data-target=""><i class="bi bi-pencil-fill bluepen"></i></a>
</div>
</li>
@endforeach
@else
<li class="list-group-item">No products found in this category.</li>
@endif
</ul>
</div>
@endforeach
</div>
@Danny971 you realise that any user can delete ANY product?
When you delete a product how does the parent of the list know? If it is also a livewire component then you need to emit an event to tell the parent to refresh.
Also, no point in sending the list of products to the view.
@Snapey well you would have to be logined to access this part of the application and once logined it you can delete any product. your statement "If it is also a livewire component then you need to emit an event to tell the parent to refresh." how do I accomplish this ? a code example would be appricated
@Danny971 How do you generate the view you showed, where you loop categories with products?
@Snapey I dont understand I place the code already. here is the whole thing
<div class="col-md-9">
<div class="tab-content">
@foreach ($categories as $category)
<div id="category-{{ $category->id }}" class="tab-pane fade">
<ul class="list-group">
<li class="list-group-item active d-flex justify-content-between align-items-center">
{{ $category->category_name }}
<div class="btn-group">
<a href="#" class="delete" data-product-id="{{ $category->id }}" data-target=""><i class="bi bi-trash text-white mr-4"></i></a>
<a href="#" class="edit" data-target=""><i class="bi bi-pencil-fill text-white mr-4"></i></a>
<a href="#" class="add" data-target=""><i class="bi bi-plus-lg text-white"></i></a>
</div>
</li>
@if ($category->products->isNotEmpty())
@foreach($category->products as $product)
<li class="list-group-item d-flex justify-content-between align-items-center">{{ $product->product_name }}
<div class="btn-group">
<livewire:delete-product :product-id="$product->id" :key="$product->id" />
<!-- <a href="#" class="delete" data-product-id="{{ $product->id }}"><i class="bi bi-trash red mr-1"></i></a> -->
<a href="#" class="edit" data-toggle="modal" data-target=""><i class="bi bi-pencil-fill bluepen"></i></a>
</div>
</li>
@endforeach
@else
<li class="list-group-item">No products found in this category.</li>
@endif
</ul>
</div>
@endforeach
</div>
here is the php
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use App\Models\Products;
use Illuminate\Support\Facades\DB;
class DeleteProduct extends Component
{
public $productId;
public function mount() {
$this->products = Products::all();
}
public function render()
{
return view('livewire.delete-product');
}
public function deleteProduct(Products $products) {
$products -> delete();
$this -> mount();
/* $product = Products::find($this->productId);
if ($product) {
$product->delete();
session()->flash('notification', ['type' => 'success', 'message' => 'Product deleted successfully']);
$this->emit('productDeleted');
$this-> mount();
} */
}
}
@Danny971 ok, you posted the WHOLE thing, so where does $categories come from?
@Snapey I have a controller called CategoryController
here is the code
public function fetchCategoryAndProductData() {
$categories = Category::with('products') -> get();
return view('categories', compact('categories'));
}
@Snapey any ideas what am doing wrong? The product is being deleted but I have to refresh the whole page. I also got the who page to reload after deleting but the purpose for me using live wire is to get the product deleted and refresh without reloading the page. I want to do it asynchronously. to see the item out without refrshing the page
@Danny971 because you delete 1 item from the list. You are doing nothing to refresh the list, and you cannot do anything to refresh the list because the list is not a livewire component, so the list is not "live"
The solution is to rewrite so that the product list is the livewire component and you are deleting one of its members
create a new compoenent CategoryProducts
in the component, accept the category id, and get all products for that category from the database and iterate over them in the blade view for the component. For the delete, call a function in the CategoryProducts component to delete from the database and then re-render the list
Please or to participate in this conversation.