jamols09's avatar

Inserting Pagination

I have this user with roles for some reason I need to manipulate the result. I used map collection so I can have the desired format of data. The issue is that when I did use the map. It removed the values of pagination such as first_page_url: "http://127.0.0.1:8000/api/admin/users?page=1", , to: 3, or total: 11 etc.

Is there a possible way to insert back the values for pagination after doing map collection?

        $userData = $this->user->paginate($limit);
        $result =  $userData->map(function ($userData) {
            return [
                'id' => $userData->id,
                'first_name' => $userData->first_name,
                'last_name' => $userData->last_name,
                'role' =>  $userData->roles()->value('name'),
            ];
        });
        return $result;

I also have a Resource file that formats the given paginated (// return UserCollection::collection($result);) values but since there are no values it causes me error such as \Collection::currentPage does not exist.

0 likes
10 replies
Sinnbeck's avatar
Sinnbeck
Best Answer
Level 102

The easiest would be to just transform it

$userData = $this->user->paginate($limit);
 $userData->transform(function ($userData) {
            return [
                'id' => $userData->id,
                'first_name' => $userData->first_name,
                'last_name' => $userData->last_name,
                'role' =>  $userData->roles()->value('name'),
            ];
        });
        return $userData;
1 like
jamols09's avatar

Unfortunately it still shows the same output Using your code I have this result

data: [
{
   id: 1,
   first_name: "Admin",
   last_name: "Admin",
   role: "Admin"
},
{
   id: 2,
   first_name: "Dominique",
   last_name: "Leannon",
   role: "Staff"
},
(...)
]

Complete output desired when displaying $this->user->paginate($limit)

data: {
current_page: 1,
data: [
{
    id: 1,
    first_name: "Admin",
    last_name: "Admin",
    email: "[email protected]"
},
{
    id: 2,
    first_name: "Dominique",
    last_name: "Leannon",
    email: "[email protected]"
},
(...)
],
first_page_url: "http://127.0.0.1:8000/api/admin/users?page=1",
from: 1,
last_page: 4,
last_page_url: "http://127.0.0.1:8000/api/admin/users?page=4",
next_page_url: "http://127.0.0.1:8000/api/admin/users?page=2",
path: "http://127.0.0.1:8000/api/admin/users",
per_page: "3",
prev_page_url: null,
to: 3,
total: 11
}
Sinnbeck's avatar

Are you doing something else with it? https://i.imgur.com/HUY2Exx.png

Route::get('fisk', function () {
    $userData = User::where('id', '>', 0)->paginate(200);
    $userData->transform(function ($userData) {
        return [
            'id' => $userData->id,
            'first_name' => $userData->first_name,
            'last_name' => $userData->last_name,
//            'role' =>  $userData->roles()->value('name'),
        ];
    });
    return $userData;
});

This is my local test.. You can see the output in the screenshot above

jamols09's avatar

Yes. I used ResourceCollection to format the pagination values Here's the sample of my code This is how I call it return UserCollection::collection($result);

public function toArray($request)
    {
        return [
            $this->collection,
            'meta' => [
                'current_page' => $this->currentPage(),
                'from' => $this->count(),
                'last_page' => $this->previousPageUrl(),
                'per_page' => $this->perPage(),
                'to' => $this->lastPage(),
                'total' => $this->total(),
            ],
            'links' => [
                'first' => url('/admin/users?page=1'),
                'last' => url('/admin/users?page=').$this->lastPage(),
                'prev' => $this->currentPage()-1,
                'next' => $this->currentPage()+1,
            ],
        ];
    }  

    public function toResponse($request)
    {
        return JsonResource::toResponse($request);
    }
jamols09's avatar

That's really weird. The pagination values on your data still persist while when I used transform instead of map the outcome is still the same.

jamols09's avatar

@sinnbeck Found the problem I did it wrong. I followed strictly your code and it actually worked.

I did this

$userData = User::where('id', '>', 0)->paginate(200);
return $userData->transform(function ($userData) {
        return [
            'id' => $userData->id,
            (..)
        ];
    });

Instead of

$userData->transform(function ($userData) {
        return [
            'id' => $userData->id,
            (...)
        ];
    });
    return $userData;

Can you help me understand why different result with such small changes?

Sinnbeck's avatar

Yeah that is confusing. When returning instantly you are returning the result of the transform, not the result of the $userData. When you do it after, the transform have been applied, and you return the transformed data :)

1 like
jamols09's avatar

Thanks! Helped me a lot now I have to learn on transform didn't even know it existed since I've been focusing too much on map.

Sinnbeck's avatar

Well most of the time map is best to use, as it does not mutate. But in this specific instance, using transform made sense :) And happy to help

Please or to participate in this conversation.