how can make a custom pagination api #41513
-
hi 'data' : [
{
// Record...
},
{
// Record...
}
],
'pagination' : [
"total": 50,
"count": 50,
"per_page": 15,
"current_page": 1,
"pre_page": 1,
"total_pages": 15,
], I solve by this solution but I repeat this code in all ResourceCollection so how I can overwrite paginate method or any solution public function index(): JsonResponse
{
$accounts = Account::with([
'userAdd:id,full_name',
'userEdit:id,full_name',
])
->when(request('name') ,fn($q) =>$q->where('name', 'LIKE', '%' . request('name') . '%'))
->when(request('phone') ,fn($q) =>$q->where('phone', 'LIKE', '%' . request('phone') . '%'))
->orderBy('created_at','desc');
return $this->getSuccessData(new PaginationAccountResource($accounts->paginate(10)));
} <?php
namespace App\Http\Resources\Account;
use Illuminate\Http\Resources\Json\ResourceCollection;
class PaginationAccountResource extends ResourceCollection
{
public function toArray($request) : array
{
return [
'data' => IndexAccountResource::collection($this->collection),
'pagination' => [
'total' => $this->total(),
'count' => $this->count(),
'perPage' => $this->perPage(),
'currentPage' => $this->currentPage(),
'totalPages' => $this->lastPage()
],
];
}
public function withResponse($request, $response)
{
$jsonResponse = json_decode($response->getContent(), true);
unset($jsonResponse['links'],$jsonResponse['meta']);
$response->setContent(json_encode($jsonResponse['data']));
}
} |
Beta Was this translation helpful? Give feedback.
Replies: 6 comments 4 replies
-
Its really easy. First, create a custom paginator that extends <?php
namespace App\Pagination;
use Illuminate\Pagination\LengthAwarePaginator;
class CustomPaginator extends LengthAwarePaginator
{
/**
* Get the instance as an array.
*
* @return array
*/
public function toArray()
{
return [
'data' => $this->items->toArray(),
'pagination' => [
'total' => $this->total(),
'count' => $this->count(),
'perPage' => $this->perPage(),
'currentPage' => $this->currentPage(),
'totalPages' => $this->lastPage(),
],
];
}
} And in your use App\Pagination\CustomPaginator;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Contracts\Pagination\LengthAwarePaginator as LengthAwarePaginatorContract;
public function register()
{
$this->app->alias(CustomPaginator::class, LengthAwarePaginator::class); // Eloquent uses the class instead of the contract 🤔
$this->app->alias(CustomPaginator::class, LengthAwarePaginatorContract::class);
} And now every time a length aware paginator is resolved from the container like Eloquent and Query Builder do, you will receive an instance of your CustomPaginator: User::paginate();
DB::table('users')->paginate(); |
Beta Was this translation helpful? Give feedback.
-
it's work if i used only paginate
IndexAccountResource class IndexAccountResource extends JsonResource
{
public function toArray($request) : array
{
return [
'id' => $this->id,
'name' => $this->name,
'manger' => $this->manger_name,
'identity' => $this->identity ?? '--',
'gender' => $this->gender,
'city' => $this->city ?? '--',
'address' => $this->address ?? '--',
'work' => $this->field_work ?? '--',
'phone' => $this->phone ?? '--',
'accountParent' => $this->parentAccount->name ?? '--',
'accountType' => $this->accountType->name,
'farisCard' => implode(' | ',$this->getCards()) ,
'userAdd' => $this->userAdd->full_name,
'userEdit' => $this->userEdit->full_name ?? '--',
'createdAt' => $this->created_at,
'updatedAt' => $this->updated_at,
];
}
} |
Beta Was this translation helpful? Give feedback.
-
I have dug in to the source of Resources and ResourceCollections and come up with a plan.
/**
* Add the pagination information to the response.
*
* @param \Illuminate\Http\Request $request
* @param array $paginated
* @param array $default
* @return array
*/
public function paginationInformation($request, $paginated, $default)
{
return Arr::only($paginated, 'pagination');
}
Thats it, quite a bit of steps, but all is working as you wanted. |
Beta Was this translation helpful? Give feedback.
-
@mikeydevelops
and this is snpit code <?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class BaseResource extends JsonResource
{
public static function collection($resource)
{
return tap(new CustomResourceCollection($resource, static::class), function ($collection) {
if (property_exists(static::class, 'preserveKeys')) {
$collection->preserveKeys = (new static([]))->preserveKeys === true;
}
});
}
}
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
use Illuminate\Support\Arr;
class CustomResourceCollection extends AnonymousResourceCollection
{
/**
* Add the pagination information to the response.
*
* @param Request $request
* @param array $paginated
* @param array $default
* @return array
*/
public function paginationInformation($request, $paginated, $default)
{
return Arr::only($paginated, 'pagination');
}
} <?php
namespace App\Http\Resources\Account;
use App\Http\Resources\BaseResource;
class IndexAccountResource extends BaseResource
{
public function toArray($request) : array
{
return [
'id' => $this->id,
'name' => $this->name,
'manger' => $this->manger_name,
'identity' => $this->identity ?? '--',
'gender' => $this->gender,
'city' => $this->city ?? '--',
'address' => $this->address ?? '--',
'work' => $this->field_work ?? '--',
'phone' => $this->phone ?? '--',
'accountParent' => $this->parentAccount->name ?? '--',
'accountType' => $this->accountType->name,
'userAdd' => $this->userAdd->full_name,
'userEdit' => $this->userEdit->full_name ?? '--',
'createdAt' => $this->created_at,
'updatedAt' => $this->updated_at,
];
}
} public function index(): JsonResponse
{
$accounts = Account::with([
'userAdd:id,full_name',
'userEdit:id,full_name',
])
->when(request('name') ,fn($q) =>$q->where('name', 'LIKE', '%' . request('name') . '%'))
->when(request('phone') ,fn($q) =>$q->where('phone', 'LIKE', '%' . request('phone') . '%'))
->orderBy('created_at','desc');
return $this->getSuccessData( IndexAccountResource::collection($accounts->paginate(10)) );
|
Beta Was this translation helpful? Give feedback.
-
@mikeydevelops |
Beta Was this translation helpful? Give feedback.
-
@mikeydevelops This solution works like a charm, but when I use the response json method, only data array values will show. Is there any way around it? Return a response from a controller with return response()->json(UserResource::collection(User::paginate(10)); The output {
"success": true,
"statusCode": 200,
"data": [
{
"id": 8,
"name": "John Doe",
"title": "Nobis esse nisi omni"
},
{
"id": 7,
"name": "John Doe",
"title": "Aute ratione hic in"
}
]
} The expected output will be {
"success": true,
"statusCode": 200,
"data": [
{
"id": 8,
"name": "John Doe",
"title": "Nobis esse nisi omni"
},
{
"id": 7,
"name": "John Doe",
"title": "Aute ratione hic in"
}
],
"pagination": {
"total": 8,
"count": 2,
"per_page": 2,
"current_page": 1,
"last_page": 4
}
} |
Beta Was this translation helpful? Give feedback.
I have dug in to the source of Resources and ResourceCollections and come up with a plan.
Together with my previous response and this you will achieve your desired result.
BaseResource
for the example, which extends the originalJsonResource
, allowing you to overwrite methods.BaseResource
somewhere I will useApp\Http\Resources\BaseResource
.class ... extends JsonResource
toclass ... extends BaseResource
.collection
method from theJsonResource
and place it in yourBaseResource
.new AnonymousResourceCollection
withnew CustomResourc…