Reputation: 24472
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:
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
Reputation: 684
Laravel 8+
$paginator = tap($this->items()->where('position', '=', null)->paginate(15),
function ($paginatorInstance) {
return $paginatedInstance->through(function ($value) {
return $value;
});
});
Upvotes: 0
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
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
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
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
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
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
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
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;
}
Upvotes: 47
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
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
Reputation: 47
Ignore the pagination in laravel and hit the normal data
foreach ($items as $item)
{
}
Upvotes: -11
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
Reputation: 1286
you have to use below code in your blade
{!! $items->render() !!}
Upvotes: -11