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

DanielRønfeldt's avatar

Reactive prop is undefined

I'm using Laravel Breeze with the Inertia/Vue stack. On an index view, I'm listing all the Booking model instances, which is working great. Each Booking component has all its necessary values incoming from the v-for loop. But I can't get access to the booking's ID inside the script tag. What am I doing wrong?

Here's the Index.vue component:

<script>
// Index.vue
import { useForm, Head, usePage } from '@inertiajs/inertia-vue3';
import { computed, ref } from 'vue';
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue';
import Booking from '@/Components/Booking.vue';

export default {
  setup(_props) {
    const bookings = computed(() => usePage().props.value.bookings);

    const form = useForm({
      message: '',
    });

    return {
      bookings,
      form,
    };
  },

  components: {
    Head,
    AuthenticatedLayout,
    Booking,
  },
};
</script>

<template>
  <Head title="Bookings"/>

  <AuthenticatedLayout>
    <div class="max-w-7xl mx-auto p-4 sm:p-6 lg:p-8">
      <div class="flex space-x-4">
        <div class="w-full">
          <div class="mt-6 bg-white shadow-md rounded-lg divide-y">
            <Booking
              v-for="booking in bookings"
              :key="booking.id"
              :booking="booking"
            />
          </div>
        </div>
      </div>
    </div>
  </AuthenticatedLayout>
</template>

And this is the Booking component (the problem occurs at the v-on:click="logThis(booking.id)" button event handler line):

<script>
// Booking.vue
import { computed, onMounted, ref } from 'vue';
import { useForm } from '@inertiajs/inertia-vue3';
import PrimaryButton from '@/Components/PrimaryButton.vue';
import Dropdown from '@/Components/Dropdown.vue';
import DropdownLink from '@/Components/DropdownLink.vue';

/**
 * Booking Data (example values)
 *
 * id:14
 * user_id:1
 * guest_name:"Michael Stuart"
 * message:"lorem ipsum dolor sit amet"
 * created_at:"2023-01-05 08:02:48"
 * updated_at:"2023-01-05 08:02:48"
 * user:Object
 *    id:1
 *    name:"Soren"
 */

export default {
  props: {
    booking: Object,
  },

  setup(_props, { emit }) {
    const form = useForm({
	    //
    });

    const logThis = (whatToLog) => {
      console.info('>>>');
      console.log(whatToLog);
      console.info('<<<');
    };

    onMounted(() => {
	    //
    });

    return {
      logThis,
      form,
    };
  },

  components: {
    DropdownLink,
    Dropdown,
  },
};
</script>

<template>
  <div class="p-6 flex space-x-2">
    <div
      class="flex justify-center items-center shadow-md bg-slate-100 rounded-xl py-0 px-4 mx-auto
      max-w-3xl mr-4"
    >
      <img
        :src="'../storage/uploads/' + booking.file_name + '_th.jpg'"
        class="w-48 h-32 rounded-sm object-cover">
    </div>

    <div class="flex-1">
      <div class="flex justify-between items-center">
        <div>
          <span class="text-gray-800">Booking created by
            <span class="text-yellow-800">{{ booking.user.name }}</span> <!-- <<< This is working (Soren)! -->
          </span>
          <small class="ml-2 text-sm text-gray-600">on
            {{ new Date(booking.created_at).toLocaleString() }} <!-- <<< This is working (1/5/2023, 10:02:48 AM)! -->
          </small>
        </div>
        <p ref="input">booking ID is {{ booking.id }}</p> <!-- <<< This is working! -->
        <Dropdown v-if="booking.user.id === $page.props.auth.user.id">
          <template #trigger>
            <button>
              <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 text-gray-400" viewBox="0 0 20 20"
                   fill="currentColor">
                <path
                  d="M6 10a2 2 0 11-4 0 2 2 0 014 0zM12 10a2 2 0 11-4 0 2 2 0 014 0zM16 12a2 2 0
                  100-4 2 2 0 000 4z"/>
              </svg>
            </button>
          </template>

          <template #content>
            <button
              class="block w-full px-4 py-2 text-left text-sm leading-5 text-gray-700
              hover:bg-gray-100 focus:bg-gray-100 transition duration-150 ease-in-out"
              v-on:click="logThis(booking.id)"><!-- <<< This is NOT working (undefined)! -->
              Testing Booking ID
            </button>
          </template>
        </Dropdown>
      </div>
      
      <p class="mt-4 text-lg text-gray-900"><small>Booking - Guest Name:</small>
        <span class="ml-2 text-md text-yellow-700 text-bold">
          {{ booking.guest_name }} <!-- <<< This is working (Michael Stuart)! -->
        </span>
      </p>
      <p class="mt-4 text-lg text-gray-900"><small>Message:</small>
        <span class="ml-2 text-md text-yellow-700 text-bold">
          {{ booking.message }} <!-- <<< This is working (lorem ipsum dolor sit amet)! -->
        </span>
      </p>
    </div>
  </div>
</template>
0 likes
13 replies
vincent15000's avatar

But I can't get access to the booking's ID inside the script tag.

I don't find inside the script tags where you try to access the booking's id.

Ok I've just seen ... it's not inside the script tags but inside the template tags.

Try to display all the bookings by adding this in the template of the booking's view.

{{ booking }}

And check if you have an id for each one.

If not, the problem comes from the datas your are passing from the server to the view.

DanielRønfeldt's avatar

@vincent15000 it's the logThis method

const logThis = (whatToLog) => {
      console.info('>>>');
      console.log(whatToLog);
      console.info('<<<');
    };

which I'm calling from within the v-on:click="logThis(booking.id)" button event handler (inside the <template> tag).

1 like
vincent15000's avatar

@DanielRønfeldt I just upated my previous answer, add {{ booking }} in the template of the booking's view.

DanielRønfeldt's avatar

@vincent15000 I'm getting all the correct data, as I specified within the template code (HTML comments). In my Index VIew, when clicking the button shown below, I should get the Booking's ID output in the browser's console. Index View But I'm getting undefined. Console

1 like
DanielRønfeldt's avatar

@vincent15000 Yes, I'm already getting the current booking's ID, see this line in my code (Booking.vue). But it "arrives" as undefined into my logThis() method.

<p ref="input">booking ID is {{ booking.id }}</p> <!-- <<< This is working! -->
1 like
DanielRønfeldt's avatar

@vincent15000 Moreover, my browser's Vue Inspection Tool is clearly showing that the <Booking> component instance has the following props:

props
	booking: Reactive
		id: 14
		user_id: 1
		guest_name: "Michael Stuart"
		message: "lorem ipsum dolor sit amet"
		created_at: "2023-01-05 08:02:48"
		updated_at: "2023-01-05 08:02:48"
1 like
vincent15000's avatar

@DanielRønfeldt Ok that's interesting to see that the booking object contains the id property and that it's accessible in the view. I think that if you tried to access another booking's property, you would have the same problem.

1 like
DanielRønfeldt's avatar

@vincent15000 so apparently I'm doing everything correctly, right? Then why can't the booking's ID be retrieved from within the button's @click handler? Any thoughts?

1 like
vincent15000's avatar

@DanielRønfeldt Yes it seems you are doing everything correctly.

But something goes wrong.

Can you try this ?

v-on:click="console.log(booking.id)"
DanielRønfeldt's avatar

@vincent15000 that's a no go, apparently console isn't recognized within the script

Uncaught TypeError: _ctx.console is undefined
1 like

Please or to participate in this conversation.