hyphen
hyphen

Reputation: 3450

Laravel Livewire component not re-rendering

I have a notifications component that I'm trying to emit an event to and get it to refresh and show new notifications to the user. I've verified that I'm receiving the event, and the refreshNotifications method is being called, but no matter what I try I can't seem to get the actual component to update. It's getting super frustrating at this point.

Here's my component:

namespace App\Http\Livewire\Components;

use Livewire\Component;
use Illuminate\Support\Facades\Auth;

class Notifications extends Component
{
    public $notifications;
    public $notificationCount = 0;

    protected $listeners = ['refreshNotifications'];

    public function mount()
    {
        $this->user = Auth::user();
    }

    public function render()
    {
        $this->notifications = $this->user->fresh()->unreadNotifications;
        $this->notificationCount = $this->user->fresh()->unreadNotifications->count();
        return view('livewire.components.notifications');
    }

    public function clearNotifications()
    {
        $this->user->unreadNotifications()->update(['read_at' => now()]);
    }

    public function refreshNotifications()
    {
        //can verify here that the event successfully emitted to this component. No refresh happens though.
        $this->render();
    }
}

And here's my blade view:

<li class="nav-item dropdown" x-data="{ open: false }">

    <a @click="open = !open" @click.outside="open = false" class="nav-link dropdown-toggle show" id="notificationDropdown" role="button">
        <i class="mdi mdi-bell-outline h3"></i>
        @if ($notificationCount)
            <div class="indicator">
                <div class="circle"></div>
            </div>
        @endif
    </a>

    <div x-show="open" class="dropdown-menu p-0 show" data-bs-popper="none">
        <div class="px-3 py-2 d-flex align-items-center justify-content-between border-bottom">
            <p>{{ $notificationCount }} New Notifications</p>
            @if ($notificationCount)
                <a role="button" wire:click="clearNotifications" class="text-muted"><i class="mdi mdi-notification-clear-all"></i>Clear all</a>
            @endif
        </div>
        @foreach ($notifications as $notification)
            <div class="px-3 py-2" wire:key="notification-{{ $notification->id }}">
                <a role="button" class="d-flex align-items-center py-2">
                    <div class="flex-grow-1 me-2">
                        <h5>{{ $notification->data['title'] ?? 'Test Title' }}</h5>
                        <p class="tx-14 text-muted"><em>{{ $notification->data['body'] ?? 'Test body' }}</em></p>

                        <p class="tx-12 text-muted">{{ Helper::timeElapsedForHumans($notification->created_at) }}</p>
                    </div>
                </a>
            </div>
        @endforeach
    </div>
</li>

Not sure if it's helpful, but the xhr response is this: {"effects":{"html":null,"dirty":[]},"serverMemo":{"checksum":"c980388fe95899e9055bfc363bd57c5d80916fe581b5b7983109cdba20db2f33"}}

Other questions on SO are related to not being in a single root element. That's not my issue. I have no idea why this isn't working. I feel like I've tried everything.

Upvotes: 2

Views: 7718

Answers (1)

Syntafin
Syntafin

Reputation: 31

You need to define what event is called in the listener, for example:

protected $listeners = ['refreshNotifications' => '$refresh'];

See here: https://laravel-livewire.com/docs/2.x/actions#magic-actions

Upvotes: -1

Related Questions