Search code examples
laravellaravel-livewire

Why ouputing user notifications in blade file I got error?


In Laravel 10 livewire 3 I show list of user notifications :

namespace App\Livewire\Personal;

use Livewire\WithPagination;

class ProfileEditor extends Component
{
    use WithPagination;
    public $notifications;
    public int $notificationsPage= 1;
    public bool $notificationsOnlyUnread= true;


    public function render(): View
    {
        $this->notifications =  auth()->user()->notifications()->latest()->paginate(2);

        return view('livewire.personal.profile-editor')->layout('components.layouts.personal');
    }

But in blade I got error :

Property type not supported in Livewire for property: [{"current_page":1,"data":[{"id":"f4bec30e-e661-4f91-aafd-a9ae623cf269","type":"App\Notifications ...

Having in template line

<table class="editor_listing_table mb-4">
    <thead class="editor_listing_table_header">
    <tr>
        <td>
            <h3 class="personal_subtitle">
                Your Notifications
            </h3>
        </td>
    </tr>
    </thead>
    @foreach($notifications as $notification)
    {{--                            {{ dd($notification)--}}
    <tr>
        <td class="editor_listing_cell whitespace-nowrap">
            {{$notification->notifiable_id}}
        </td>
        <td class="editor_listing_cell whitespace-nowrap">
            {{$notification->notifiable_type}}
        </td>

    </tr>
    @endforeach
</table>

@if(count($notifications) > 0)
<div class="livewire-pagination">
    {{ $notifications->onEachSide(2)->links(data: ['scrollTo' => false]) }}
</div>
@endif

If to uncomment line with

dd($notification)

I see :

enter image description here With DatabaseNotification class for any row item.

If in dd to use toArray method I see valid row of data, but anyway this

Property type not supported ...

error and I do not know how to fix it ? Actuall I do not refer "type" field in my blade file


Solution

  • You don't need this to be a live property, so you can pass it as a variable to the view instead.

    First, remove the property

    public $notifications;
    

    Then update your render method, to pass it in via the view() data argument.

    public function render(): View 
    { 
        $notifications = auth()->user()->notifications()->latest()->paginate(2); 
    
        return view('livewire.personal.profile-editor', [
                'notifications' => $notifications,
            ])
            ->layout('components.layouts.personal'); 
    }
    

    This change means that you now pass the variable into the view, rather it being a property of the component-class (which is then exposed as a variable in the view).

    This is an important change for Livewire, as any data can be passed into the view like we now do above, but not all types can be set as public properties of a Livewire-class.

    A public property in the Livewire-class needs to be re-hydrated on each subsequent request (Livewire will serialize it so that it can replicate its exact state when re-hydrating), and only a limited number of types are supported by default. Pagination is not one of those.