TheUnreal
TheUnreal

Reputation: 24472

Laravel change pagination data

My Laravel pagination output is like laravel pagination used to be, but I need to change the data array for each object. My output is:

Output

As you can see, the data object has 2 items, which I need to change.

My code is:

$items = $this->items()
        ->where('position', '=', null)
        ->paginate(15);

Which returns the user items with pivot table, but I don't like the way the pivot table is shown in the JSON, so I decided to change the items and organize each item with the pivot before the item.

For this purpose, I tried to use foreach

foreach ($items->data as $item)
        {

        }

which giving my an error, for a reason I don't know:

Undefined property: Illuminate\Pagination\LengthAwarePaginator::$data"
status_code: 500

Any help?

Upvotes: 53

Views: 89513

Answers (14)

Luke Watts
Luke Watts

Reputation: 684

Laravel 8+

$paginator = tap($this->items()->where('position', '=', null)->paginate(15), 
function ($paginatorInstance) {
    return $paginatedInstance->through(function ($value) {
    return $value;
});
    
});

Upvotes: 0

dragonfire
dragonfire

Reputation: 702

Laravel 8.9.0 has added the through method to AbstractPaginator.
It transforms each item in the slice of items using a callback, and keeps the items paginated.

$paginator = $this->items()->where('position', '=', null)->paginate(15);
$paginator->through(function ($value) {
    // Your code here
    return $value;
});

The source code:

/**
 * Transform each item in the slice of items using a callback.
 *
 * @param  callable  $callback
 * @return $this
 */
public function through(callable $callback)
{
    $this->items->transform($callback);

    return $this;
}

Upvotes: 7

Kidd Tang
Kidd Tang

Reputation: 2241

This is your paginated items...

$items = $this->items()
        ->where('position', '=', null)
        ->paginate(15);

I am using Laravel 8, can simply use each

$items->each(function ($item) {
 // your code here
 $item->custom_data = calcSomeData(); // sample
});

It does the same as this...

$items->getCollection()->transform(function ($item) {
 // your code here
 $item->custom_data = calcSomeData(); // sample
});

Upvotes: 0

Kirill Nizhnikov
Kirill Nizhnikov

Reputation: 1

Laravel AbstractPaginator has methods setCollection() and getCollection()

<?php

$itemsPaginated = $this->items()->paginate(15);
$itemsPaginated->setCollection(
    $itemsPaginated->getCollection()->transform(function ($item) {
       // Your code here
       return $item;
    })
)

Upvotes: 0

pankaj
pankaj

Reputation: 1906

Sample Example :

    $franchiseData=[ 'id'=>1 ,'name'=>'PAnkaj'];
    $models = $bookingsQuery->paginate(10);
    $models->setCollection(collect($franchiseData));
    return  $models;

Note that $models->setCollection(collect($franchiseData)); you have to use collect() else you will get error.

Upvotes: 3

Koushik Das
Koushik Das

Reputation: 10793

getCollection

is one way to get the items. Another way is to use this For ex- Assuming, user doesn't have name param and only have first_name and last_name

$userPaginatedData = User::paginate(15);
$users = $userPaginatedData->items();

foreach($users as $user) {
   $user->name = $user->first_name . ' ' . $user->last_name;
}


return $userPaginatedData;

Now in the data key, you would see that each user has name param with it.

Upvotes: 2

Murwa
Murwa

Reputation: 2278

The paginator's items is a collection. You can grab it and transform the data like so:

$paginator = $this->items()->where('position', '=', null)->paginate(15);
$paginator->getCollection()->transform(function ($value) {
    // Your code here
    return $value;
});

If you are familiar with tap helper here is the snippet that does exact same.

$paginator = tap($this->items()->where('position', '=', null)->paginate(15),function($paginatedInstance){
    return $paginatedInstance->getCollection()->transform(function ($value) {
        return $value;
    });
});

We can't chain method getCollection to paginator instance because AbstractPaginator will return paginator's underlying collection. so the paginator instance will be transformed to Collection. So fix that we can use tap helper.

Upvotes: 144

Christian Ndukwe
Christian Ndukwe

Reputation: 9

<?php 

$itemsPaginated = $this->items()->paginate(15);

$itemsPaginated = json_encode($itemsPaginated);

foreach ($itemsPaginated->data as $key => $item) {
    $results->data[$key]; //Modify
}

$itemsPaginated = json_encode($results);

Upvotes: -1

Scofield
Scofield

Reputation: 4735

There is a setCollection method for such purpose.

$items = Model::paginate(10);

$updatedItems = $items->getCollection();

// data manipulation
// ...

$items->setCollection($updateItems);

From the source code of /Illuminate/Pagination/AbstractPaginator.php

/**
* Set the paginator's underlying collection.
*
* @param  \Illuminate\Support\Collection  $collection
* @return $this
*/
public function setCollection(Collection $collection)
{
    $this->items = $collection;

    return $this;
}

Source

Upvotes: 47

hellovoid
hellovoid

Reputation: 621

If you'd like to keep items paginated:

        $itemsPaginated = $this->items()
             ->paginate(15);

        $itemsTransformed = $itemsPaginated
            ->getCollection()
            ->map(function($item) {
                return [
                    'id' => $item->id,
                ];
        })->toArray();

        $itemsTransformedAndPaginated = new \Illuminate\Pagination\LengthAwarePaginator(
            $itemsTransformed,
            $itemsPaginated->total(),
            $itemsPaginated->perPage(),
            $itemsPaginated->currentPage(), [
                'path' => \Request::url(),
                'query' => [
                    'page' => $itemsPaginated->currentPage()
                ]
            ]
        );

Upvotes: 53

umihico
umihico

Reputation: 307

I could make shorter way. This returns edited $array instead of simple $paginated. This example modify file names. This doc was useful for me.

    $paginated=$query->paginate(12);
    $array=$paginated->toArray();
    foreach ($array['data'] as $r=>$record) {
        $array['data'][$r]->gif=$array['data'][$r]->gif.".gif";
    }
    return $array;

Upvotes: 2

hamedkke
hamedkke

Reputation: 47

Ignore the pagination in laravel and hit the normal data

foreach ($items as $item)
{

}

Upvotes: -11

Dzung Nguyen
Dzung Nguyen

Reputation: 67

-Laravel 5.4

// example update column "photo" 
// from "/path/to/photo.png" 
// to "abc.com/path/to/photo.png"
foreach ($items as $item)
{
    $path = $item->photo;

  // Remove 
  $item->offsetUnset("photo");

  // Set
  $item->offsetSet("photo", url($path));
}

Upvotes: 1

Veerendra Borra
Veerendra Borra

Reputation: 1286

you have to use below code in your blade

{!! $items->render() !!}

Upvotes: -11

Related Questions