Search code examples
phplaravellaravel-8laravel-livewirealpine.js

Alpine issues with blade component toaster notification


in my project I use Laravel 8, Livewire and Alpine.js.

My livewire toaster code (app\Http\Livewire\ToasterNotification.php):

<?php
    
namespace App\Http\Livewire;
    
use Livewire\Component;
    
class ToasterNotification extends Component
{
    public $notifications = array();
    protected $listeners = ['notificationUpdate', 'notificationRemove'];
    
    public function notificationUpdate($notif)
    {
        array_push($this->notifications, $notif);
        $this->dispatchBrowserEvent('toast-message-show');
    }
    
    public function notificationRemove($id)
    {
        unset($this->notifications[$id]);
    }

    public function render()
    {
        return view('livewire.toaster-notification');
    }
}

Which executes this blade (resources\views\livewire\toaster-notification.blade.php) and he will call a blade component named toaster on "x-toaster":

<div
    wire:poll.5s
    aria-live="polite"
    aria-atomic="true"
    style="z-index:1200; position: absolute; top: 70px; right: 20px; min-height: 200px;"
>
    @foreach($notifications as $i => $notification)
        <x-toaster id="{{ $i }}" message="{{ $notification['message'] }}" color="{{ $notification['color'] }}"/>
    @endforeach
</div>

(resources\views\components\toaster.blade.php):

<div
    class="toaster toastAlert show border-{{ $color }}"
    style="min-width: 250px"
    data-autohide="false"
    role="alert"
    aria-live="assertive"
    aria-atomic="true"
    id="toastAlert{{ $id }}"
>
    <div class="toast-header">
        <svg class="bd-placeholder-img rounded mr-2 bg-{{ $color }}" width="20" height="20" focusable="false" role="img">
            <rect width="100%" height="100%" fill="#ffffff00"></rect>
        </svg>
        <strong class="mr-auto">{{ $message }}</strong>
        <button type="button" class="ml-2 mb-1 close" wire:click="notificationRemove({{ $id }})">
            <span aria-hidden="true">&times;</span>
        </button>
    </div>
</div>

I want improve the old system which reloads every 5s and use alpine along livewire if possible. Actually my code looks like this :

<script defer src="https://unpkg.com/alpinejs@3.9.0/dist/cdn.min.js"></script>

<style> [x-cloak] { display: none !important; } </style>
    
<div
    x-data="{show:false}"
    @toast-message-show.window="
        show = true;
        setTimeout(() => show=false, 5000);
    "
    x-show="show"
    x-cloak
>
    @foreach($notifications as $i => $notification)
        <x-toaster id="{{ $i }}" message="{{ $notification['message'] }}" color="{{ $notification['color'] }}"/>
    @endforeach
</div>

But I have no display. I think there is an issue because nothing is executed while in the foreach. I've tried to add some test messages like

<h1 x-data="{ message: 'I ❤️ Alpine' }" x-text="message"></h1>

But nothing worked out.


Solution

  • Ok i found out the answer, it was messy but i had to remove the style and put the src in the blade app.