Home > Blockchain >  laravel - pagination on collection
laravel - pagination on collection

Time:04-04

Im trying to work on eloquent collection. Got User model and Article model with relation one to many. One User can have many Articles. One Article belongs to one User.

This is how I retrieve articles written by a specifield user in a controller:

public function articles(User $user) {
    if(empty($user)) $user = Auth::user();
    $articles = $user->articles->paginate(10); //here comes collection

    // passing results to view
    return view('articles.index', compact('articles'))
        ->with('i', (request()->input('page', 1) - 1) * 10);
}

I found many solutions for paginating results that are a collection. The on I like the most is here: https://stackoverflow.com/a/56142421/14330487

My code is same. Using laravel 9, php 8.1.3 right now on a new project. I've created Collection::macro in AppServiceProvider boot() method.

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\Collection;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        // builtin bootstrap views for pagination
        Paginator::useBootstrapFive();

        /**
         * Paginate 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,
                ]
            );
        });
    }
}

Dont know why my VSC shows me that forPage() and count() methods are undefined... I dont get any errors running my app. But also cant see any results.

Routing, controller and view is fine, when Im doing it another way it shows results, but the way I get it is a crap. Using Collection::macro is far more gentle.

I have in my AppServiceProvider.php file lines like use Illuminate\Support\Collection and LengthAwarePaginator.

Really dont know why it doesnt work. Maybe its laravel 9 fault? Solution I found looks like made for laravel 8.

Thanks for help.

CodePudding user response:

Use this function

firstItem()

lastItem()

total()

links()

Example

#Controller

$orders = DB::table('orders')->paginate(15);

#View

$orders->firstItem();

$orders->lastItem();

$orders->total();

$orders->links();

CodePudding user response:

I've done that another way, without AppServiceProvider, but just by creating a Helper class. Solution found here: https://sam-ngu.medium.com/laravel-how-to-paginate-collection-8cb4b281bc55

My first attepmt did not work cause of method articles argument default value declaration. Should looks like:

public function articles(User $user = null) {}

and not known definition of forPage() and count() method are just display errors from VSC.

Both solutions works fine.

Just considering now which attempt is better.

  • Related