Search code examples
laravelpaginationlaravel-8laravel-livewire

Livewire throwing error when using paginated data


So I am being given this error when trying to paginate my data and send it in to a view through a livewire component.

I am trying to get all posts and display at max 5 posts per page using pagination in laravel.

Livewire version: 2.3.1
Laravel version: 8.13.0

Error:

Livewire\Exceptions\PublicPropertyTypeNotAllowedException
Livewire component's [user-posts] public property [posts] must be of type: [numeric, string, array, null,
or boolean]. Only protected or private properties can be set as other types because JavaScript doesn't
need to access them.

My Component:

<?php

namespace App\Http\Livewire;

use Livewire\Component;
use App\Models\Post;
use Livewire\WithPagination;

class UserPosts extends Component
{
    use WithPagination;

    public $posts;
    public $type;
    protected $listeners = ['refreshPosts'];



    public function delete($postId)
    {
        $post = Post::find($postId);
        $post->delete();
        $this->posts = $this->posts->except($postId);
    }

    public function render()
    {
        if($this->type == 'all')
            $this->posts = Post::latest()->paginate(5);
        else if($this->type == 'user')
            $this->posts = Post::where('user_id',Auth::id())->latest()->paginate(5);
        return view('livewire.user-posts', ['posts' => $this->posts]);
    }
}

My Blade:

<div wire:poll.5s>
    @foreach($posts as $post)
        <div style="margin-top: 10px">
            <div class="post">
                <div class="flex justify-between my-2">
                    <div class="flex">
                        <h1>{{ $post->title }}</h1>
                        <p class="mx-3 py-1 text-xs text-gray-500 font-semibold"
                           style="margin: 17px 0 16px 40px">{{ $post->created_at->diffForHumans() }}</p>
                    </div>
                    @if(Auth::id() == $post->user_id)
                        <i class="fas fa-times text-red-200 hover:text-red-600 cursor-pointer"
                           wire:click="delete({{$post->id}})"></i>
                    @endif
                </div>
                <img src="{{ asset('image/banner.jpg') }}" style="height:200px;"/>
                <p class="text-gray-800">{{ $post->text }}</p>
                @livewire('user-comments', [
                    'post_id' => $post->id,
                    'type' => 'all'
                    ],
                    key($post->id)
                )
            </div>
        </div>
    @endforeach
        {{ $posts->links() }}
</div>


Solution

  • $posts should not be declared as a property in the Livewire component class, you passed the posts with the laravel view() helpers as data.

    Remove the line

    public $posts;
    

    And replace $this->posts by $posts in the render function:

        public function render()
        {
            if($this->type == 'all')
                $posts = Post::latest()->paginate(5);
            else if($this->type == 'user')
                $posts = Post::where('user_id',Auth::id())->latest()->paginate(5);
            return view('livewire.user-posts', ['posts' => $posts]);
        }
    }