Search code examples
laravel-8eventemitterlaravel-livewire

Laravel livewire does not emit events


I am trying to create a small toast message dispatcher for livewire components within my Laravel solution but the event emission does not work.

I have the ToastMessage.php file with this code

namespace App\Http\Livewire;

use Livewire\Component;

class ToastMessage extends Component
{
    protected $listeners = ['showToast' => 'showToast'];

    public $alertTypeClasses = [
        'success' => ' bg-green-500 text-white',
        'warning' => ' bg-orange-500 text-white', 
        'danger' => ' bg-red-500 text-white', 
    ];

    public $message = 'Notification Message';

    public $alertType = 'success';
    
    public function render()
    {
        return view('livewire.toast');
    }

    public function showToast($message, $alertType)
    {
        $this->message = $message;
        $this->alertType = $alertType;

        $this->dispatchBrowserEvent('toast-message-show');
    }
}

and this corresponding template

<div class="fixed top-0 right-0 inset-x-0 mb-6 mx-6 px-6 py-5 max-w-sm rounded-lg pointer-events-auto {{ $alertTypeClasses[$alertType] }}"
    x-data="{show:false}" @toast-message-show.window="show = true; setTimeout(() => show=false, 5000);" x-show="show" x-cloak>
    {{ $message }}
</div>

I try to show the toast after saving some data inside another components like this:

public function save()
{
    // saving my data, this works

    $this->emit('showToast', 'Your data has been saved', 'success');
}

The problem is that $this->emit does not work. I don't get any errors or anything. I could even add some gibberish as parameters for the emission and it doesn't even crash.

What am I missing. Livewire's documentation falls short when it comes to debugging things


Solution

  • You can do it more simple. Create a blade file, for example in partials/flash-messages.php

    @if ($message = Session::get('success'))
        <div class="fixed top-0 right-0 inset-x-0 mb-6 mx-6 px-6 py-5 max-w-sm rounded-lg pointer-events-auto bg-green-500 text-white">
        {{ $message }}
    </div>
    @endif
    
    @if ($message = Session::get('warning'))
        <div class="fixed top-0 right-0 inset-x-0 mb-6 mx-6 px-6 py-5 max-w-sm rounded-lg pointer-events-auto bg-orange-500 text-white">
        {{ $message }}
    </div>
    @endif
    
    @if ($message = Session::get('danger'))
        <div class="fixed top-0 right-0 inset-x-0 mb-6 mx-6 px-6 py-5 max-w-sm rounded-lg pointer-events-auto bg-red-500 text-white">
        {{ $message }}
    </div>
    @endif
    

    in your blades component

    @if(session()->has('message'))
       @include('partials.flash-messages')
    @endif
    

    and in component

    public function save()
    {
       //....
       session()->flash('success', 'This is the message');
    }