connecteev's avatar

How to modify Laravel's returned paginated data ?

My code is calling a Laravel API which returns data in this format:

{
    "current_page": 2,
    "data": [
        {
            "id": 36,
            "title": "Error perferendis aut velit quaerat.",
        },
        {
            "id": 124,
            "title": "Beatae nobis voluptatum incidunt animi voluptatem ea quod veniam.",
        }
    ],
    "first_page_url": "http://localhost:8000/api/v1/me/getPostsWithMyReactions?page=1",
    "from": 16,
    "last_page": 6,
    "last_page_url": "http://localhost:8000/api/v1/me/getPostsWithMyReactions?page=6",
    "next_page_url": "http://localhost:8000/api/v1/me/getPostsWithMyReactions?page=3",
    "path": "http://localhost:8000/api/v1/me/getPostsWithMyReactions",
    "per_page": 15,
    "prev_page_url": "http://localhost:8000/api/v1/me/getPostsWithMyReactions?page=1",
    "to": 30,
    "total": 78
}

After the result is returned, I would like to APPEND to the 'data' key while preserving the rest of the meta data for Laravel's pagination.

So, this is my desired result:

{
    "current_page": 2,
    "data": [
        {
            "id": 36,
            "title": "Error perferendis aut velit quaerat.",
            "bookmarked": 1,
        },
        {
            "id": 124,
            "title": "Beatae nobis voluptatum incidunt animi voluptatem ea quod veniam.",
            "bookmarked": 1,
        }
    ],
    "first_page_url": "http://localhost:8000/api/v1/me/getPostsWithMyReactions?page=1",
    "from": 16,
    "last_page": 6,
    "last_page_url": "http://localhost:8000/api/v1/me/getPostsWithMyReactions?page=6",
    "next_page_url": "http://localhost:8000/api/v1/me/getPostsWithMyReactions?page=3",
    "path": "http://localhost:8000/api/v1/me/getPostsWithMyReactions",
    "per_page": 15,
    "prev_page_url": "http://localhost:8000/api/v1/me/getPostsWithMyReactions?page=1",
    "to": 30,
    "total": 78
}

However, doing the following doesn't quite cut it:

$postsArray = $getPostsApiResponse->getData()->data;
foreach ($postsArray as $postObj) {
    $postObj->bookmarked = 1;
}
return $getPostsApiResponse;

Here, if I return $getPostsApiResponse, the data remains unchanged ("bookmarked": 1 isn't present). If I return $postsArray, the data is changed (it has "bookmarked": 1 in all the array's keys), but I lose all the pagination metadata (first_page_url, from, to, etc).

Does anyone know of a way to modify the data key while preserving the rest of the metadata? Ideally in a clean (the Laravel) way? Thanks for your help!

0 likes
7 replies
connecteev's avatar

tried:

        $getPostsApiResponse->setData($postsArray); // see https://laravel.com/api/5.3/Illuminate/Http/JsonResponse.html#method_setData
connecteev's avatar

@jlrdw thanks for chiming in!

See my comment above.

Btw, I saw your link and googled 'length aware paginator' for laravel, but it's not clear WHEN and WHY it is to be used. What is the use-case for the length aware paginator?

connecteev's avatar
connecteev
OP
Best Answer
Level 11

@jlrdw thanks! So I guess the length aware aginator is for more fine grained control and manual pagination with DB facades.

Re: the original problem, here's how I fixed it in the end..for future reference. Blew an entire afternoon on this :( but at least it works now.

$getPostsApiResponseArr = $getPostsApiResponse->getData(true);
$postsArray = $getPostsApiResponseArr['data'];

// make changes to $postsArray

$getPostsApiResponseArr['data'] = $postsArray; // Need to preserve the rest of the (original) Laravel pagination data
$getPostsApiResponse->setData($getPostsApiResponseArr); // see https://laravel.com/api/5.3/Illuminate/Http/JsonResponse.html#method_setData
return $getPostsApiResponse;

AlexeyPlodenko's avatar

Since this page comes in Google searching for the solution.

Here is the solution I got with Laravel 12:

/** @var \Illuminate\Pagination\LengthAwarePaginator $paginator */
$paginator->through(function ($post) {
	$post = $post->toArray();
	$post['tags'] = array_map(fn (array $tag) => $tag['name'], $post['tags']);
	return $post;
});
1 like
krisi_gjika's avatar

@AlexeyPlodenko and before 12:

/** @var \Illuminate\Pagination\LengthAwarePaginator $posts */
$posts->getCollection()->transform(function (Post $post) use ($user) {
    $post->bookmarked = in_array($post->id, $user->bookmarked_posts);
	return $post;
});

Please or to participate in this conversation.