0

I'm developing a project with Laravel 9, Inertia and Vue 3. When I provide a Collection of records from the database to a Vue page with Inertia, the values come as a prop, a Proxy array of objects, which I can check if .length is bigger than zero, I can check if .every(i => i !== undefined), but when I iterate over it, it throws an uncaught in promise exception on console.

The ProfessionalsController.php

/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
   $professionals = Professional::all();

   return Inertia::render('Professionals/Index', ['professionals' => $professionals]);
}

The Professional/Index.vue

<script setup>
import { Head } from '@inertiajs/inertia-vue3';
import { watch } from '@vue/runtime-core';

const props = defineProps({professionals: Array});

console.log(props.professionals, props.professionals.length, props.professionals[0].id);
</script>
<template>
    <Head title="Médicos" />

    <template v-if="professionals.length > 0 && professionals.every(i => !! i)">
        <ul >
             <li for="(index, professional) in professionals" :key="index">
                                    Nome: {{  professional.name }}<br>
                                    CRM: {{ professional.crm }}<br>
             </li>
        </ul>
    </template>
</template>

Here, the data comes. The console.log in the script, prints it.

Proxy {0: {…}, 1: {…}, 2: {…}, 3: {…}, 4: {…}, 5: {…}, 6: {…}, 7: {…}, 8: {…}, 9: {…}}
[[Handler]]: Object
[[Target]]: Array(10)
0: {id: 1, name: 'Carol Roque', crm: 'WN85149439', phone: '98775-0784', created_at: '2022-05-08T03:51:34.000000Z', …}
1: {id: 2, name: 'Diego Duarte Filho', crm: 'RU07697438', phone: '96712-3272', created_at: '2022-05-08T03:51:34.000000Z', …}
2: {id: 3, name: 'Dr. Ricardo Carrara Fidalgo', crm: 'CM55958226', phone: '97367-5229', created_at: '2022-05-08T03:51:34.000000Z', …}
3: {id: 4, name: 'Sr. Jorge Jean Romero', crm: 'NF71422476', phone: '93156-1833', created_at: '2022-05-08T03:51:34.000000Z', …}
4: {id: 5, name: 'Marta Galindo', crm: 'IB95085501', phone: '3048-2031', created_at: '2022-05-08T03:51:34.000000Z', …}
5: {id: 6, name: 'Dr. Lidiane Lia Ferraz', crm: 'PX86614139', phone: '2854-6792', created_at: '2022-05-10T03:53:15.000000Z', …}
6: {id: 7, name: 'Adriano Ícaro Ferminiano Neto', crm: 'KQ93046167', phone: '95618-8435', created_at: '2022-05-10T03:53:15.000000Z', …}
7: {id: 8, name: 'Dr. Erik Bittencourt', crm: 'YB92798968', phone: '90151-4721', created_at: '2022-05-10T03:53:15.000000Z', …}
8: {id: 9, name: 'Dr. Dayana Ortega Batista Neto', crm: 'RU93839397', phone: '91844-2628', created_at: '2022-05-10T03:53:15.000000Z', …}
9: {id: 10, name: 'Stefany de Aguiar', crm: 'UX32957687', phone: '99495-4536', created_at: '2022-05-10T03:53:15.000000Z', …}
length: 10
[[Prototype]]: Array(0)
[[IsRevoked]]: false

But when it comes to the template, the items are undefined:

app.js:23938 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'name')

I even placed a concole.log(professional) inside the li tag, it only prints undefined

I'm guessing that although the professionals prop is reactive, it's items are not. But I can't find anything exactly about it, and no way of correcting that behavior. Already tried:

  • change to options api
  • wrap professionals in a async/await arrow function in the v-for directive
  • pass the prop.professional to a data state, using ref and asyncData
  • extract the array from the Proxy with the value() method
2
  • 2
    Directive for list rendering is v-for but you have only for in template. When used with array the first alias is an item and second alias is index - (professional, index) in professionals Commented May 10, 2022 at 15:01
  • 1
    Thanks MichalLevý! I think I should have just sleep sooner last night Commented May 10, 2022 at 15:03

1 Answer 1

1

As Michal Levý mentioned, I was not using the correct Vue directive v-for but only a for instead.

Also, I misplaced the alias for the index with the one for the object I was trying to access:

before

<template v-if="professionals.length > 0 && professionals.every(i => !! i)">
    <ul >
        <li for="(index, professional) in professionals" :key="index">
            Nome: {{  professional.name }}<br>
            CRM: {{ professional.crm }}<br>
        </li>
    </ul>
</template>

after

<template v-if="professionals.length > 0 && professionals.every(i => !! i)">
    <ul >
        <li v-for="(professional, index) in professionals" :key="index">
            Nome: {{  professional.name }}<br>
            CRM: {{ professional.crm }}<br>
        </li>
    </ul>
</template>

(actually I'm using professional.id as the key directive, but just to clarify, the order of the aliases was wrong too)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.