Directives v-if and v-for not rendering expected data in a vuejs3 application

31 Views Asked by At

I am making a small application for appointment booking, using vue3 with setup script syntax. Firstly, I use the @vuepic/vue-datepicker component to display a monthly calendar on the screen and record the user's date selection. The selected date retrieves a list of available times from a restful api, and then must display that list as a list of buttons containing the different times that can be chosen. The logic is that when a button is pressed, the date and time desired by the user are recorded, and then move on to a second step where personal data will be requested. (this is just for informational purposes, there are no problems with that step) The problem is that I store the list of retrieved schedules in a reactive variable called appointments, which is defined as follows:

const appointments = ref(null);

At the moment, the information for that variable is a fake list that respects the format that the API will return:

let hours = {
  slots: [
    {
      startDate: "2023-11-21T11:00:00+0000",
      zonedStartDate: "2023-11-21T08:00:00-0300",
      availability: 1,
      defaultDuration: 30,
    },
    {
      startDate: "2023-11-21T11:30:00+0000",
      zonedStartDate: "2023-11-21T08:30:00-0300",
      availability: 1,
      defaultDuration: 30,
    },
    {
      startDate: "2023-11-21T12:00:00+0000",
      zonedStartDate: "2023-11-21T09:00:00-0300",
      availability: 1,
      defaultDuration: 30,
    },
    {
      startDate: "2023-11-21T12:30:00+0000",
      zonedStartDate: "2023-11-21T09:30:00-0300",
      availability: 1,
      defaultDuration: 30,
    },
    {
      startDate: "2023-11-21T13:00:00+0000",
      zonedStartDate: "2023-11-21T10:00:00-0300",
      availability: 1,
      defaultDuration: 30,
    },
    {
      startDate: "2023-11-21T13:30:00+0000",
      zonedStartDate: "2023-11-21T10:30:00-0300",
      availability: 1,
      defaultDuration: 30,
    },
    {
      startDate: "2023-11-21T14:00:00+0000",
      zonedStartDate: "2023-11-21T11:00:00-0300",
      availability: 1,
      defaultDuration: 30,
    },
    {
      startDate: "2023-11-21T14:30:00+0000",
      zonedStartDate: "2023-11-21T11:30:00-0300",
      availability: 1,
      defaultDuration: 30,
    },
    {
      startDate: "2023-11-21T15:00:00+0000",
      zonedStartDate: "2023-11-21T12:00:00-0300",
      availability: 1,
      defaultDuration: 30,
    },
    {
      startDate: "2023-11-21T15:30:00+0000",
      zonedStartDate: "2023-11-21T12:30:00-0300",
      availability: 1,
      defaultDuration: 30,
    },
  ],
};

This way when the user clicks on a date, I assign the fake array to the appointments variable and at the same time I make a console.log of appointments.value to verify the assignment

// fake change date -> asign fake data to appointments
const handleDateChange = () => {
  appointments.value = hours.slots;
  console.log(appointments.value[0]); // it shows hours array in console
};

By inspecting the console I can see the expected data array, and consequently this should be displayed in the template next to the calendar like this:

    <div class="grid grid-cols-1 lg:grid-cols-2">
      <VueDatePicker
        v-model="selectedDate"
        :min-date="minDate"
        :max-date="maxDate"
        ignore-time-validation
        prevent-min-max-navigation
        inline
        auto-apply
        locale="es"
        :enable-time-picker="false"
        :disabled-week-days="[6, 0]"
        week-start="0"
        calendar-cell-class-name="dp-custom-cell"
      />
      <div class="px-8 pt-20">
        <div class="grid grid-cols-2 gap-4" v-if="appointments">
          <button
            v-for="slot in appointments.value"
            :key="slot.zonedStartDate"
            class="px-6 py-2 transition border rounded-lg border-gray-light hover:bg-gray-dark hover:text-gray-light focus:bg-gray-dark focus:text-gray-light"
            @click="handleClick"
          >
            {{ slot.zonedStartDate }}hs
          </button>
        </div>
      </div>
    </div>

I'm using v-if="appointments" because when trying with v-if="appointments.value" or v-if="appointments.value.length > 0" it fires an undefined error. Anyway, no buttons are rendered in the v-if zone.

In order to show what I'm saying, I created a project in stackblitz, which can be seen at the following [address](In order to show what I'm saying, I created a project in stackblitz, which can be seen at the following address: https://stackblitz.com/edit/vuepic-vue-datepicker-3dsu7d?file=src%2Fcomponents%2FPlayground.vue)

0

There are 0 best solutions below