Reputation: 95
I have a page where I need to show a paginated list of posts. Before now, my controller was:
$posts = Post::whereNotNull('published_at')->paginate(10);
return view('index', compact('posts'));
Then in my view index.blade.php
I could do something like:
@foreach ($posts as $post)
<h3 class="mb-4"><a href="{{$post->link}}">{{$post->title}}</a></h3>
@endforeach
Now I need to limit the query to only 50 posts. However, the below code snippet fails since laravel pagination uses limit internally which overrides my own query. So I still get all the posts in the database:
$posts = Post::whereNotNull('published_at')->limit(50)->paginate(10);
return view('index', compact('posts'));
So I used the Illuminate\Pagination\LengthAwarePaginator
to create a manual paginator. So now my controller looks like:
$page = LengthAwarePaginator::resolveCurrentPage();
$perPage = 10;
$results = Post::whereNotNull('published_at')->limit(50)->get();
$items = array_slice($results->toArray(), ($page - 1) * $perPage, $perPage);
$posts = new LengthAwarePaginator($items, count($results), $perPage, $page);
return view('index', compact('posts'));
My index.blade.php
remains the same. But now if I try to visit the page, I get an error like
Trying to get property 'link' of non-object
It turns out that in my index.blade.php
, each $post
in $posts
is an array instead of an instance of the Post
class.
How can I get each $post
in $posts
to be an object (an instance of the Post
class)? Ideally, I would like the view to work just the way it is without modification.
I appreciate all the efforts.
Upvotes: 0
Views: 593
Reputation: 42710
Laravel's Collection
object has many built-in methods to act like an array. Instead of converting your results to an an array and using array_slice
:
$items = array_slice($results->toArray(), ($page - 1) * $perPage, $perPage);
You should use the Collection::slice()
method.
$items = $results->slice(($page - 1) * $perPage, $perPage);
Upvotes: 1