Problem
When working with Laravel and Inertia.js, pagination returns an object instead of an array. This can make looping over the results a bit tricky, as the expected array structure isn’t accessible.
For example, in a typical Laravel controller method like this:
public function publicIndex()
{
$latestPosts = Post::orderBy('created_at', 'desc')->paginate(5);
return Inertia::render('Welcome', [
'latestPosts' => $latestPosts,
]);
}
You might see the data coming through correctly as a prop in your Vue component, but attempting to loop over latestPosts
directly results in empty output.
Solution
The issue is due to how Laravel paginate()
function structures the data. Instead of a direct array, it returns an object with additional pagination metadata, as this below:
{
"headers": {},
"original": {
"current_page": 1,
"data": [
{
"id": 1,
"title": "Aspernatur aut assumenda qui ea.",
"company": "Beatty, Dooley and Klein",
"created_at": "2024-10-16T17:28:21.000000Z",
"updated_at": "2024-10-16T17:28:21.000000Z"
}
],
"total": 1
},
"exception": null
}
To access the posts data, you need to use latestPosts.original.data
instead of latestPosts
directly.
Vue Component Example in this case
To set up your Vue component properly, define the prop as an object and access original.data
for looping:
<template>
<div>
<ul v-if="latestPosts.original && latestPosts.original.data.length">
<li v-for="post in latestPosts.original.data" :key="post.id">
{{ post.title }}
</li>
</ul>
</div>
</template>
<script setup>
import { defineProps } from 'vue';
const props = defineProps({
latestPosts: {
type: Object,
default: () => ({}),
},
});
</script>
Hope this helps!