Defining and listening to custom events in Laravel Livewire

Video thumbnail

The next thing we are going to do would be to define an event, that is, dispatch an event similar to what we already did with the cart one we have here, dispatch an event with the parameter when we perform any of the CRUD operations like delete, update, or create. So, later we will listen to this from here and display the toast. That's the meaning of it, so if you have the same problem as me, at least for now, please comment this out. We will solve this in the following classes and make the final details so that it doesn't give you an error, which is a section that appears for me, so well, let's go.

We left off knowing about Livewire's JavaScript, which is a fundamental piece for using custom events that occur on the client and server.

Events in Livewire serve to communicate that “something occurred” within a component. It could be that a product was added to the cart, that a post was updated, or that the user deleted a record.

On a practical level, I use them when I want the UI to react automatically to backend actions: displaying a toast, refreshing components, or updating another component that isn't directly connected.

"Refresh" Property

So, what do I want to talk about with regard to refresh? Now that's clear, what we're trying to achieve is reload that component. To do this, we have a refresh property in Laravel Livewire, as we discussed earlier. The idea is that when changes occur in any of the sibling components, we notify the parent component, and it updates its state using the refresh property:

class General extends Component
{
  ***
   protected $listeners = ['stepEvent'];
   
   
class Person extends Component
{
   ***
   function submit()
   {
       ***
       $this->dispatch('stepEvent', 3);
   }

Communication Between Components

In Livewire, one component can tell another:

"Hey, I just created an item, react as you need to."

This flow becomes very clear when you do CRUD. In my case, when I add or modify a product in the cart, I fire:

$this->dispatch("itemAdd", $post);

https://www.desarrollolibre.net/blog/laravel/laravel-livewire-introduction-to-javascript

Events to JavaScript

This is where Livewire shines. From JS you can listen to events like this:

Livewire.on('itemAdd', (params) => {
   toast('Item agregado: ' + params[0].title, options);
});

This connection is what makes it possible to display toasts, open modals, or execute any frontend logic without touching AJAX or writing boilerplate.

Livewire 2 vs Livewire 3: Important Changes

This is the point where many get lost (including myself at first). If you come from Livewire 2, it changes quite a bit.

From emit() to dispatch()

Before (v2):

$this->emit('evento');

Now (v3):

$this->dispatch('evento');

Functionally it is the same: launching an event. Only the name changes.

From $listeners to #[On]

Before (v2):

protected $listeners = ['evento' => 'método'];

Now (v3):

#[On('evento')]
public function método() { ... }

How to Emit Custom Events in Livewire

Emitting events in Livewire 3 is as easy as calling dispatch() inside any component method.

$this->dispatch("itemAdd", $post);

When I do cart CRUD, I fire different events:

$this->dispatch("itemChange", $post); $this->dispatch("itemDelete");

It is useful to pass the full post because I then use it for the toast:

toast('Item updated: ' + params[0].title, options)

Real Example with CRUD (add, update, delete)

Here is an example identical to the one I use:

public function add($post, $count = 1)
{
   if ($count <= 0) {
       $this->dispatch("itemDelete");
       return;
   }
   if (Arr::exists($cart, $post['id'])) {
       $cart[$post['id']][1] = $count;
       $this->dispatch("itemChange", $post);
   } else {
       $cart[$post["id"]] = [$post, $count];
       $this->dispatch("itemAdd", $post);
   }
}

This pattern makes the flow of actions very readable.

How to Listen for Events with #[On] in your Components

In Livewire, listening for events is as easy as placing the attribute above the method.

#[On('itemAdd')] public function actualizarCarrito($post) { // I update table, total, or whatever I need }

Handling Multiple Events in the Same Component

You can listen for as many as you want:

#[On('itemAdd')] #[On('itemChange')] #[On('itemDelete')] public function refreshCart() { $this->loadCart(); }

Common Errors I've Seen (and Suffered)

  • Not using #[On] correctly.
  • Having a return before the dispatch.
  • A typo in the event name (“itemAddd”).
  • Executing dispatch from a component without it being properly mounted.
  • Having live sections in the layout that are not compatible (it happened to me; I ended up commenting them out to avoid errors while I solved it).

Listening for Events from JavaScript (toasts, modals, alerts)

Video thumbnail

This part is key when you want instant UI feedback.

Toast-me Configuration

I install it like this:

npm i toast-me

Then, in resources/js/app.js:

import toast from 'toast-me';
window.toast = toast;
const options = {
   position: 'bottom'
};
Livewire.on('evento'): ejemplo completo
Livewire.on('itemAdd', (params) => {
   toast('Item agregado: ' + params[0].title, options)
})
Livewire.on('itemChange', (params) => {
   toast('Item actualizado: ' + params[0].title, options)
})
Livewire.on('itemDelete', () => {
   toast('Item eliminado del carrito', options)
})

The:

window.toast = toast

is configured so that if you want to use it anywhere else, you could do it from the window object, or rather, you already have it configured in the window object, and you could use it anywhere. So I set toast equal to toast, I set a constant here, and this var will be to handle the position:

const options = { position:'bottom' }

For the rest, you can use it based on Livewire events, for example:

resources/js/app.js

Livewire.on('itemAdd', (params) => {
   toast('Item add to cart: ' + params[0].title, options)
})

From the components:

$this->dispatch("itemAdd",$post);

Next step, learn about the functioning of requests to synchronize properties and events

I agree to receive announcements of interest about this Blog.

Let's learn how to create custom events in Laravel Livewire and listen to them on the client using JavaScript.

| 👤 Andrés Cruz

🇪🇸 En español