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)