7

I want to use map or transform in paginated collection in laravel 5.5 but I am struggling it work

This is what I was trying to do but getCollection is not available in LengthAwarePaginator as what we used to do in previous laravel versions see: How to transform paginated collection

 $query = User::filter($request->all()
        ->with('applications');

    $users = $query->paginate(config('app.defaults.pageSize'))
        ->transform(function ($user, $key) {
            $user['picture'] = $user->avatar;

            return $user;
        });

This is what I receive but there is no pagination details in my result

enter image description here

How can I return transformed collection with pagination details?

Theodory Faustine
  • 432
  • 2
  • 10
  • 22

5 Answers5

18

For Laraval >= 8.x: if you want to perform the transform() on the collection of the paginated query builder result instead of doing the pagination on the full collection, one can use the method through():

User::filter($request->all()
   ->with('applications')
   ->paginate(config('app.defaults.pageSize'))
   // through() will call transform() on the $items in the pagination object
   ->through(function ($user, $key) {
      $user['picture'] = $user->avatar;

      return $user;
   });

corneyl
  • 418
  • 1
  • 5
  • 10
5

I have ended up building custom paginate function in AppServiceProvider

use Illuminate\Support\Collection;

In register of AppServiceProvider

 Collection::macro('paginate', function ($perPage, $total = null, $page = null, $pageName = 'page') {
        $page = $page ?: \Illuminate\Pagination\LengthAwarePaginator::resolveCurrentPage($pageName);
        return new \Illuminate\Pagination\LengthAwarePaginator(
            $this->forPage($page, $perPage),
            $total ?: $this->count(),
            $perPage,
            $page,
            [
                'path' => \Illuminate\Pagination\LengthAwarePaginator::resolveCurrentPath(),
                'pageName' => $pageName,
            ]
        );
    });
Theodory Faustine
  • 432
  • 2
  • 10
  • 22
3

You should paginate before retrieving the collection and transforming as follows:

$query = User::filter($request->all())->with('applications')->paginate(50);

$users = $query->getCollection()->transform(function ($user, $key) {
    //your code here
});

dd($users);

It should give you your desired result.

rkg
  • 805
  • 5
  • 14
  • I have tried that but getCollection is not available in laravel 5.5 so its not working to me it returns same results as above picture of my results there is not pagination details – Theodory Faustine Sep 10 '19 at 09:37
1

You can use method setCollection from Paginator class: https://laravel.com/api/8.x/Illuminate/Pagination/Paginator.html#method_setCollection

$messages = $chat->messages()->paginate(15);

$messages->setCollection($messages->getCollection()->transform(function($item){
  $item->created = $item->created_at->formatLocalized('%d %B %Y %H:%M');
  return $item;
}));
h5xde
  • 61
  • 5
0

Your problem is that you are printing the $users variable that hold the array of the users in the current page. To get the paginated list try to return/print $query instead.

So your code should be as following:

    $query = User::filter($request->all()
            ->with('applications');
    
        $users = $query->paginate(config('app.defaults.pageSize'))
            ->transform(function ($user, $key) {
                $user['picture'] = $user->avatar;
    
                return $user;
            });
return response()->json($query);

Happy Coding!