Search code examples
javascriptarraysdatetime-format

How to create an array with time slots based on preexisting data with javascript


I am making an app for my thesis an I need help with a specific problem I am trying to solve. Let me describe the functionality i want to achive first.

In my front end I want the user to able to pick an appointment date and time. The way I am thinking to do this is to have him pick a specific date. When he submits the date I want to generate an array of available time slots in the following way.

In my db I have shop objects. Each shop has an array of appointmetns. Each appointment has a starting hour and an ending hour. For reasons of simplicity I am having the time slot set to 30 minutes for every appointment eg if the starting hour is 14:00 the ending hour is 14:30. So after the customer submits the date I retrieve with a query all the appointments for that specific date. My shops are, again for simplicity open every day from 8:00 to 21:00.

With that in mind I want to create an array that starts from 8:00 ends at 21:00 and the interval is thirty minutes. But I want to dynamicaly create this array based on the existing appointments meaning that if there is an appointment starting at 14:30 the time slot 14:30 - 15:00 will not be inserted in the array.

I have a crud way of doing this by hardcoding an array with all timeslots from 8:00 to 9:00 and then an array dynamicaly with appointment timeslots. Then i make a third array by filtering the to arrays. I would your help to find a way to do this more dynamicaly in order to have different opening times across shops and different time duration for each appointment in the feature.

E.G

const shop = {
    user: "fakeid123",
    title: "Barber Shop",
    description: "fake description",
    appointments: [{
            customername: "Kostas",
            start: "12:00",
            end: "12:30"
        },
        {
            customername: "Makis",
            start: "13:00",
            end: "13:30"
        },
        {
            customername: "Kostas",
            start: "14:00",
            end: "14:30"
        },
        {
            customername: "Kostas",
            start: "17:00",
            end: "17:30"
        }
    ],
    opens: "8:00",
    closes: "21:00"
};

Base on the example above the array should be :

[
    8: 00 - 8: 30
    8: 30 - 9: 00
    9: 00 - 9: 30
    9: 30 - 10: 00
    10: 30 - 11: 00
    11: 00 - 11: 30
    11: 30 - 12: 00
    12: 30 - 13: 00
    13: 30 - 14: 00
    14: 30 - 15: 00
    15: 00 - 15: 30
    ....
    16: 30 - 17: 00
    18: 00 - 18: 30
    ...
    20: 30 - 21: 00
]

The timeslots 12:00-12:30 13:00-13:30 14:00-14:30 and 17:00-17:30 are not in the array

I am doing it this way in order to present the customer with a drop down menu with available time slots to pick.

The start and end fields are string but are time formats. How can I iterate over them to create the array? Thanks in advance


Solution

  • You're provided a time range with shop.opens and shop.closes. This is a very good point to start with. You can generate other time ranges for appointments from this. Think of it this way :

    function generateAppointments(shop) {
        let appointments = [];
        let [hoursOp, minutesOp] = shop.opens.split(":"); //here you retrieve hours and minutes from your input string
        let [hoursCl, minutesCl] = shop.closes.split(":");
        let timeRange = Number.parseInt(hoursCl) - Number.parseInt(hoursOp);
    
        for (let i = 0; i < timeRange; i++) { //here you iterate for the whole range of hours you are given
            const appHourStart = Number.parseInt(hoursOp) + i;
            //here you check if the appointment is already booked
            //this is a lot of iteration, maybe you could find a better way to approach this
            //I made it what with came to my mind first
            const firstHalfBooked = shop.appointments.some(a => a.start === `${appHourStart}:00`); 
            const secondHalfBooked = shop.appointments.some(a => a.start === `${appHourStart}:30`);
    
            //here, you only create a array element if the spot isn't booked
            if(!firstHalfBooked) appointments.push(`${appHourStart}:00 - ${appHourStart}:30`);
            if(!secondHalfBooked) appointments.push(`${appHourStart}:30 - ${appHourStart+1}:00`);
        }
    
        console.log (appointments);
        return appointments;
    }
    

    Hope this helps, and you can understand it.

    Edit: I kept the minutes for the "opens" and "closes" field so you can anticipate in case a shop opens say at 8:30.