How to paginate a collection after get() in Laravel?

Solution 1:

best way for paginate collection:

1- add this to boot function in \app\Providers\AppServiceProvider

  /**
         * Paginate a standard Laravel Collection.
         *
         * @param int $perPage
         * @param int $total
         * @param int $page
         * @param string $pageName
         * @return array
         */
        Collection::macro('paginate', function($perPage, $total = null, $page = null, $pageName = 'page') {
            $page = $page ?: LengthAwarePaginator::resolveCurrentPage($pageName);
            return new LengthAwarePaginator(
                $this->forPage($page, $perPage),
                $total ?: $this->count(),
                $perPage,
                $page,
                [
                    'path' => LengthAwarePaginator::resolveCurrentPath(),
                    'pageName' => $pageName,
                ]
            );
        });

2-From hereafter for all collection you can paginate like this

$events1 = \App\Event::Where('valid_to','>=',$today)->orderByRaw('valid_to','ASC')->get();
$events2 = \App\Event::Where('valid_to','<',$today)>orderByRaw('valid_to','ASC')->get();
$events = $events1->merge($events2); 

$events->paginate(5)

Solution 2:

You're calling links() and render() on the wrong object. You've assigned the paginator to the $pagination variable. You should be calling

$pagination->links()

or

$pagination->render()

Also, if you'd like to clean this up a little bit, you can modify your query so that you only have one query and don't need to combine two different result sets. You just need to first order on the result of the date comparison, and then order on your valid_to field.

$events = \App\Event::orderByRaw('valid_to < ?', [$today])->orderBy('valid_to')->get();

The date comparison will return a true/false result. In ASC order (default when not specified), true results will come after false results, so rows where the valid_to is less than $today (expired) will come after the rows where valid_to is greater than or equal to $today.

That result set will then be ordered by the valid_to field itself. This one query gives you the same results as the two queries you've manually merged. And, of course, you can just paginate this one query:

$events = \App\Event::orderByRaw('valid_to < ?', [$today])->orderBy('valid_to')->paginate(60);

Now, it is your $events object that is paginated, so you would want to use $events->links() and $events->render().