skip to Main Content

I’m working on a Laravel project with Livewire, and I have a component where I want to trigger a method called filterRows when a link is clicked.

However, the method doesn’t seem to be triggering, and I’m not sure what I’m missing.

Here’s the relevant code snippet from my Livewire view:

<!-- Livewire view code -->
    <div>
        <li class="relative" x-data="{ open: false }">
            <button class="relative align-middle rounded-md focus:outline-none focus:shadow-outline-purple"
                @click="open = !open" @keydown.escape="open = false" @click.away="open = false" aria-label="Notifications"
                aria-haspopup="true">
                <svg class="w-5 h-5" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20">
                    <path
                        d="M10 2a6 6 0 00-6 6v3.586l-.707.707A1 1 0 004 14h12a1 1 0 00.707-1.707L16 11.586V8a6 6 0 00-6-6zM10 18a3 3 0 01-3-3h6a3 3 0 01-3 3z">
                    </path>
                </svg>
                <!-- Notification badge -->
                @if ($notificationsCounts->count() > 0)
                    <span aria-hidden="true"
                        class="absolute -top-1 -right-1 inline-flex w-3 h-3   bg-red-600 border-2 border-white rounded-full dark:border-gray-800  text-white animate-pulse">
                    </span>
                @endif
            </button>
          
            <template  x-if="open" @keydown.escape="open = false"  @click.away="open = false">
                <ul x-transition:leave="transition ease-in duration-150"          x-transition:leave-start="opacity-100"
                    x-transition:leave-end="opacity-0"
                    class="absolute right-0 w-56 p-2 mt-2 space-y-2 text-gray-600 bg-white border border-gray-100 rounded-md shadow-md dark:text-gray-300 dark:border-gray-700 dark:bg-gray-700">
                   
                    @foreach ($notifications as $notification)                   
                        <li class="flex">
                            <a class="inline-flex items-center justify-between w-full px-2 py-1 text-sm font-semibold transition-colors duration-150 rounded-md hover:bg-gray-100 hover:text-gray-800 dark:hover:bg-gray-800 dark:hover:text-gray-200"
                                href="#" {{-- wire:key="'notif'- $notif->id " --}} 
                                wire:key="'{{ 'notif-' . $notification->id }}"
                                wire:click.prevent="filterRows('{{ $notification->model }}', '{!! $notification->id !!}' )"
                                >
                                <span>{{ class_basename($notification->model) }}</span>
                                <span
                                    class="inline-flex items-center justify-center px-2 py-1 text-xs font-bold leading-none text-red-600 bg-red-100 rounded-full dark:text-red-100 dark:bg-red-600">
                                    {{ $notification->message }}
                                </span>
                            </a>
                        </li>
                    @endforeach
                </ul>
            </template>
        </li>       
    </div>

the view is included on the navbar as component

 <livewire:notifications  />

And here’s the relevant code snippet from my Livewire component:

<?php  
namespace AppHttpLivewire;

use IlluminateSupportFacadesDB;
use LivewireComponent;
use AppModelsNotification;
use IlluminateSupportFacadesAuth;

class Notifications extends Component
{
    public $notifs;
    public $selectedModel;
    public $notificationsCounts;

   

    public function mount()
    {
        $this->refreshNotifications();
    }

    public function refreshNotifications()
    {
        $this->notificationsCounts = Notification::select('model', DB::raw('COUNT(*) as count'))
            ->where('is_read', 0)
            ->where('user_id', Auth::id())
            ->groupBy('model')
            ->get();
    }

    public function render()
    {
        $this->notifs = Notification::where('is_read', 0)
            ->where('user_id', Auth::id())
            ->get();

        return view('livewire.notifications', [
            'notifications' => $this->notifs,
            'notificationsCounts' => $this->notificationsCounts,
        ]);
    }

    public function filterRows($model, $id)
    {
        $this->selectedModel = $model;

        // Update the is_read field to 1 for the corresponding model
        Notification::where('model', $model)
            ->where('user_id', Auth::id())
            ->update(['is_read' => 1]);

        // Refresh the notifications data
        $this->refreshNotifications();
        
        // Perform any other filtering logic or redirect as needed
    }
}

I’ve verified that Livewire is set up correctly in my project, and I have other Livewire components working as expected.data is displayed normaly (

<span>{{ class_basename($notif->model) }}</span>)

However, in this particular case, the filterRows method is not being triggered.

Am I missing something in my Livewire view or component code? Any help or guidance would be greatly appreciated.

2

Answers


  1. Chosen as BEST ANSWER

    it seems that the issue lies with the usage of <template x-if="open" ...>; when I replaced it with <div x-show ...>, it worked perfectly


  2. Either it’s a typo or you’re miraculously not getting an exception for your wire:key, as the dash is outside the string and not concatted:

    wire:key="'notif'- $notif->id "
    
    should be
    
    wire:key="'notif-' . $notif->id"
    

    In the case your $notif->id isn’t numeric, you should ensure it’s in quotes:

    wire:click.prevent="filterRows('{{ $notif->id }}')"
    

    Besides the fact you have a li without parent (ol/ul/), your HTML looks fine.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search