Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

CamKem's avatar
Level 10

Help remapping an array / collection

Hello, I have an array that is like this:

array:8 [▼ // routes/web.php:57
  1 => "https://demo.test/users?page=1"
  2 => "https://demo.test/users?page=2"
  3 => "https://demo.test/users?page=3"
  4 => "https://demo.test/users?page=4"
  5 => "https://demo.test/users?page=5"
  6 => "https://demo.test/users?page=6"
  7 => "https://demo.test/users?page=7"
  8 => "https://demo.test/users?page=8"
]

I would like to remap it, so that it is friendly to use for pagination links in Vue. This is how I would like it to look like (or however it would need to be displayed that it will work with the way I render my pagination below)

'links' => [
    'label' => 1
    'url' =>  "https://demo.test/users?page=1"
]

This is how I display my pagination:

        <div v-if="links">
            <div v-for="(link, key) in links" :key="key">
                <a v-if="link.url" :href="link.url">{{ link.label }}</a>
                <span v-else>{{ link.label }}</span>
            </div>
        </div>

This is the code I have in my route that is passing the data to the view.

Route::get('/users', function () {
    sleep(1);
    $users = User::paginate(15);
    $mapped = $users->map(function ($user) {
        return [
            'id' => $user->id,
            'name' => $user->name,
            'email' => $user->email,
            'created_at' => $user->created_at->format('d/m/Y'),
        ];
    });
    $links = $users->links();
    //dd($links['elements'][0]);
    return Inertia::render('Users', [
        'users' => $mapped,
        'pagination' => [
            'links' => $links['elements'][0],
            'currentPage' => $users->currentPage(),
            'lastPage' => $users->lastPage(),
            'perPage' => $users->perPage(),
            'total' => $users->total(),
        ],
    ]);
})->name('users');

The reason I am using $links['elements'][0], is when I just directly use $users->links() to send to Vue (client), it gives an empty object. This is extremely frustrating, because if I was not array mapping the data, I could just use users.links for the pagination object & it works perfectly!

I'm open to any other better method of doing this, surely this is a problem lots of people have come accross any there is an elegant solution to handling pagination with array mapping.

0 likes
5 replies
LaryAI's avatar
Level 58

To remap the array to the desired format, you can use the map method on the original array and return a new array with the desired keys and values. Here's an example:

$originalArray = [
    1 => "https://demo.test/users?page=1",
    2 => "https://demo.test/users?page=2",
    3 => "https://demo.test/users?page=3",
    4 => "https://demo.test/users?page=4",
    5 => "https://demo.test/users?page=5",
    6 => "https://demo.test/users?page=6",
    7 => "https://demo.test/users?page=7",
    8 => "https://demo.test/users?page=8",
];

$remappedArray = collect($originalArray)->map(function ($url, $label) {
    return [
        'label' => $label,
        'url' => $url,
    ];
})->values()->toArray();

// Output:
// [
//     [
//         'label' => 1,
//         'url' => 'https://demo.test/users?page=1',
//     ],
//     [
//         'label' => 2,
//         'url' => 'https://demo.test/users?page=2',
//     ],
//     ...
// ]

In this example, we first convert the original array to a Laravel collection using the collect function. Then, we use the map method to iterate over each key-value pair in the collection and return a new array with the desired keys and values. Finally, we use the values method to reset the keys of the collection to consecutive integers starting from 0, and the toArray method to convert the collection back to a plain PHP array.

To use this remapped array in your pagination links, you can pass it to your view as follows:

return Inertia::render('Users', [
    'users' => $mapped,
    'pagination' => [
        'links' => $remappedArray,
        'currentPage' => $users->currentPage(),
        'lastPage' => $users->lastPage(),
        'perPage' => $users->perPage(),
        'total' => $users->total(),
    ],
]);

Then, in your Vue component, you can iterate over the links array as follows:

<div v-if="pagination.links">
    <div v-for="(link, key) in pagination.links" :key="key">
        <a v-if="link.url" :href="link.url">{{ link.label }}</a>
        <span v-else>{{ link.label }}</span>
    </div>
</div>
CamKem's avatar
Level 10

@LaryAI This work's, but it loose the nice tidy dynamically updated links object that laravel produces when you send a whole paginated collection over, such as the the next & previous buttons that included & the active element too. This is frustrating if I now have to reproduce this just because I mapped an array that was paginated.

Please help! Surely there is a better solution.

EDIT: I tried to reproduce the next & previous links, but as I need to compute them inside of the v-for & use a v-if statement to check if the current key is the last key, I can't work out how to then pass the correct link.url into the href, this is a nightmare... I really need to work out how to get the standard pagination props passed through to Vue by laravel, even when a map is being done on a collection.

@snapey or @sinnbeck can either of you help me on this one? I am majorly stumped.

MichalOravec's avatar
Level 75

You can use through for mapping there result.

$users = User::paginate(15)->through(function ($user) {
    return [
        'id' => $user->id,
        'name' => $user->name,
        'email' => $user->email,
        'created_at' => $user->created_at->format('d/m/Y')
    ];
});
MaverickChan's avatar

If you want to use some Vue pagination, try query . Basiclly , pagination is a query like

path/route/getposts?page=1

so , if you get a collction from backend , structure like

{
data: [...],
total_page: ,
current_page,
next_page_url...
}

then in your axios get request , write a query append to the url remember , keep the query reactive

Please or to participate in this conversation.