inertiajs / inertia

Inertia.js lets you quickly build modern single-page React, Vue and Svelte apps using classic server-side routing and controllers.
https://inertiajs.com
MIT License
6.19k stars 417 forks source link

Laravel Inertia pagination issue #899

Closed swilliamrobert closed 2 years ago

swilliamrobert commented 2 years ago

Versions:

Describe the problem:

Hi, I am having an issue with inertia pagination link while loading the categories list.

The categories.links is returning undefined. Not sure why the vue component can't identify the links object. I am expecting the links object to use for pagination. I don't see this in my Vue props.

[Vue warn]: Error in render: "TypeError: Cannot read properties of undefined (reading 'length')"

Can you please help me to resolve this issue? Thanks.

Please see the below code.

Laravel7 and Vue2

Category Controller:

 public function index()
    {
       return Inertia::render('Category/Index', [
            'categories' => MarketplaceCategory::with('vendor')->paginate(4)
                ->transform(fn ($category) => [
                    'id' => $category->id,
                    'name' => $category->name,
                    'vendor' => $category->vendor['name'],
                    'status' => ($category->status) ? 'Active' : 'Inactive',
                ]),
        ]);
    }

Category Index Component:

<template>
    <div class="container-fluid p-0">
        <div class="col-12 col-xl-12">
            <div class="card">
                <div class="card-header">
                    <div class="flex-grow-1">
                        <InertiaLink class="float-right btn btn-primary" :href="'categories/create'"><i
                            class="fa fa-plus" style="font-size: 12px;"></i> <span class="">Add Category</span>
                        </InertiaLink>
                    </div>
                    <h3>List Categories</h3>

                </div>
                <table class="table table-striped">
                    <thead>
                    <tr>
                        <th>Category</th>
                        <th>Actions</th>
                    </tr>
                    </thead>
                    <tbody>
                    <tr v-for="item in categories.data" :key="item.id">
                        <td>{{ item.name }}</td>
                        <td class="table-action">
                            <InertiaLink :href=CategoryEditLink(item.id)><i class="fas fa-pen"
                                                                            style="font-size: 14px;"></i></InertiaLink>
                            <InertiaLink :href=CategoryDeleteLink(item.id)><i class="fas fa-trash"
                                                                              style="font-size: 14px;"></i>
                            </InertiaLink>
                        </td>
                    </tr>

                    </tbody>
                </table>
            </div>
            <pagination :links="categories.links"/>

        </div>
    </div>
</template>

<script>
    import Layout from "../Shared/Layout";
    import Pagination from "../Shared/Pagination";

    export default {
        metaInfo: {title: 'Vendor'},
        layout: Layout,
        components: {
            Pagination,
        },
        props: {
            categories: Object,
            vendor: Object,
        },
         mounted() {
            console.log(this.categories.links);
        },
        methods: {
            CategoryEditLink: function (id) {
                return 'categories/edit/' + id;
            },
            CategoryDeleteLink: function (id) {

                return 'categories/delete/' + id;
            },
        }
    }
</script>

Pagination Component:


<template>
    <div v-if="links.length > 3">
        <div class="flex flex-wrap -mb-1">
            <template v-for="(link, key) in links">
                <div v-if="link.url === null" :key="key" class="mr-1 mb-1 px-4 py-3 text-sm leading-4 text-gray-400 border rounded" v-html="link.label" />
                <inertia-link v-else :key="key" class="mr-1 mb-1 px-4 py-3 text-sm leading-4 border rounded hover:bg-white focus:border-indigo-500 focus:text-indigo-500" :class="{ 'bg-white': link.active }" :href="link.url" v-html="link.label" />
            </template>
        </div>
    </div>
</template>

<script>
    export default {
        props: {
            links: Array,
        },
    }
</script>

The actual pagination link from the laravel.

"first_page_url": "http://market.localhost.test/admin/categories?page=1",
  "from": 1,
  "last_page": 2,
  "last_page_url": "http://market.localhost.test/admin/categories?page=2",
  "next_page_url": "http://market.localhost.test/admin/categories?page=2",
  "path": "http://market.localhost.test/admin/categories",
  "per_page": 10,
  "prev_page_url": null,
  "to": 10,
  "total": 15
dillingham commented 2 years ago

try categories.meta.links

claudiodekker commented 2 years ago

Could you try using ->through() instead of ->transform()?

In either case, since I'm cleaning up issues, I'll be closing this one for now. If you feel like it's definitely an Inertia issue, and my suggestion didn't work, then feel free to re-open this 👍