getTimeSlots( )
Returns a list of time slots at a given restaurant on a given date
, and their availability for a given partySize
.
Description
Without passing optional parameters, the list will contain a single time slot at the given date
.
Use slotsBefore
and slotsAfter
to get additional time slots before and after the given date
.
If you do not provide a duration
, the duration will be calculated automatically based on the reservation location's configuration.
The reservation location's settings used to determine the duration are its defaultTurnoverTime
and turnoverTimeRules
. These specify how much time should be allotted for a reservation of a party of a given size.
The startDate
s of time slots in the response are 15 minutes apart regardless of the duration
provided.
Syntax
function getTimeSlots(reservationLocationId: string, date: Date, partySize: number, options: GetTimeSlotsOptions): Promise<GetTimeSlotsResponse>
getTimeSlots Parameters
NAME
TYPE
DESCRIPTION
ID of the reservation location for which to retrieve time slots.
Date and time for which to retrieve a time slot.
Size of the party that needs to be seated during this time slot.
Min: 1
Options for retrieving the time slots.
Returns
Return Type:
NAME
TYPE
DESCRIPTION
A list of time slots and their availability according to the given party size.
Was this helpful?
1import { timeSlots } from 'wix-table-reservations-v2';23/* Sample reservationLocationId value: 'fab8cc1f-31cf-462f-b5bb-392594624bf2'4 * Sample date value: new Date("2023-12-29T12:30:00Z")5 * Sample partySize value: 26 */78timeSlots.getTimeSlots(reservationLocationId, new Date(date), partySize)9 .then((retrievedSlots) => {10 const firstStartDate = retrievedSlots.items[0].startDate;11 const firstStatus = retrievedSlots.items[0].status;1213 console.log('Success! Retrieved the following time slots:', retrievedSlots);14 return retrievedSlots;15 })16 .catch((error) => {17 console.error(error);18 // Handle the error19 });2021/* Promise resolves to:22 * {23 * "timeSlots": [24 * {25 * "startDate": "2023-12-29T10:00:00.000Z",26 * "duration": 90,27 * "status": "AVAILABLE",28 * "tableCombinations": [29 * {30 * "tableIds": [31 * "1ed802ae-708f-4da6-9177-54c3df5d3dd5"32 * ]33 * }34 * ],35 * "manualApproval": false36 * },37 * {38 * "startDate": "2023-12-29T10:15:00.000Z",39 * "duration": 90,40 * "status": "AVAILABLE",41 * "tableCombinations": [42 * {43 * "tableIds": [44 * "1ed802ae-708f-4da6-9177-54c3df5d3dd5"45 * ]46 * }47 * ],48 * "manualApproval": false49 * },50 * {51 * "startDate": "2023-12-29T10:30:00.000Z",52 * "duration": 90,53 * "status": "AVAILABLE",54 * "tableCombinations": [55 * {56 * "tableIds": [57 * "1ed802ae-708f-4da6-9177-54c3df5d3dd5"58 * ]59 * }60 * ],61 * "manualApproval": false62 * },63 * {64 * "startDate": "2023-12-29T10:45:00.000Z",65 * "duration": 90,66 * "status": "AVAILABLE",67 * "tableCombinations": [68 * {69 * "tableIds": [70 * "1ed802ae-708f-4da6-9177-54c3df5d3dd5"71 * ]72 * }73 * ],74 * "manualApproval": false75 * },76 * {77 * "startDate": "2023-12-29T11:00:00.000Z",78 * "duration": 90,79 * "status": "AVAILABLE",80 * "tableCombinations": [81 * {82 * "tableIds": [83 * "1ed802ae-708f-4da6-9177-54c3df5d3dd5"84 * ]85 * }86 * ],87 * "manualApproval": false88 * },89 * {90 * "startDate": "2023-12-29T11:15:00.000Z",91 * "duration": 90,92 * "status": "UNAVAILABLE",93 * "tableCombinations": [],94 * "manualApproval": false95 * },96 * {97 * "startDate": "2023-12-29T11:30:00.000Z",98 * "duration": 90,99 * "status": "UNAVAILABLE",100 * "tableCombinations": [],101 * "manualApproval": false102 * },103 * {104 * "startDate": "2023-12-29T11:45:00.000Z",105 * "duration": 90,106 * "status": "UNAVAILABLE",107 * "tableCombinations": [],108 * "manualApproval": false109 * },110 * {111 * "startDate": "2023-12-29T12:00:00.000Z",112 * "duration": 90,113 * "status": "UNAVAILABLE",114 * "tableCombinations": [],115 * "manualApproval": false116 * },117 * {118 * "startDate": "2023-12-29T12:15:00.000Z",119 * "duration": 90,120 * "status": "UNAVAILABLE",121 * "tableCombinations": [],122 * "manualApproval": false123 * },124 * {125 * "startDate": "2023-12-29T12:30:00.000Z",126 * "duration": 90,127 * "status": "UNAVAILABLE",128 * "tableCombinations": [],129 * "manualApproval": false130 * },131 * {132 * "startDate": "2023-12-29T12:45:00.000Z",133 * "duration": 90,134 * "status": "UNAVAILABLE",135 * "tableCombinations": [],136 * "manualApproval": false137 * },138 * {139 * "startDate": "2023-12-29T13:00:00.000Z",140 * "duration": 90,141 * "status": "UNAVAILABLE",142 * "tableCombinations": [],143 * "manualApproval": false144 * },145 * {146 * "startDate": "2023-12-29T13:15:00.000Z",147 * "duration": 90,148 * "status": "UNAVAILABLE",149 * "tableCombinations": [],150 * "manualApproval": false151 * },152 * {153 * "startDate": "2023-12-29T13:30:00.000Z",154 * "duration": 90,155 * "status": "UNAVAILABLE",156 * "tableCombinations": [],157 * "manualApproval": false158 * },159 * {160 * "startDate": "2023-12-29T13:45:00.000Z",161 * "duration": 90,162 * "status": "UNAVAILABLE",163 * "tableCombinations": [],164 * "manualApproval": false165 * },166 * {167 * "startDate": "2023-12-29T14:00:00.000Z",168 * "duration": 90,169 * "status": "AVAILABLE",170 * "tableCombinations": [171 * {172 * "tableIds": [173 * "1ed802ae-708f-4da6-9177-54c3df5d3dd5"174 * ]175 * }176 * ],177 * "manualApproval": false178 * },179 * {180 * "startDate": "2023-12-29T14:15:00.000Z",181 * "duration": 90,182 * "status": "AVAILABLE",183 * "tableCombinations": [184 * {185 * "tableIds": [186 * "1ed802ae-708f-4da6-9177-54c3df5d3dd5"187 * ]188 * }189 * ],190 * "manualApproval": false191 * },192 * {193 * "startDate": "2023-12-29T14:30:00.000Z",194 * "duration": 90,195 * "status": "AVAILABLE",196 * "tableCombinations": [197 * {198 * "tableIds": [199 * "1ed802ae-708f-4da6-9177-54c3df5d3dd5"200 * ]201 * }202 * ],203 * "manualApproval": false204 * },205 * {206 * "startDate": "2023-12-29T14:45:00.000Z",207 * "duration": 90,208 * "status": "AVAILABLE",209 * "tableCombinations": [210 * {211 * "tableIds": [212 * "1ed802ae-708f-4da6-9177-54c3df5d3dd5"213 * ]214 * }215 * ],216 * "manualApproval": false217 * },218 * {219 * "startDate": "2023-12-29T15:00:00.000Z",220 * "duration": 90,221 * "status": "AVAILABLE",222 * "tableCombinations": [223 * {224 * "tableIds": [225 * "1ed802ae-708f-4da6-9177-54c3df5d3dd5"226 * ]227 * }228 * ],229 * "manualApproval": false230 * }231 * ]232 * }233 */234
This example gets a 5-minute time slot at the selected date, and the next 5-minute time slot after it.
1import { timeSlots } from 'wix-table-reservations-v2';23/* Sample reservationLocationId value: 'fab8cc1f-31cf-462f-b5bb-392594624bf2'4 * Sample date value: new Date("2023-12-29T12:30:00Z")5 * Sample partySize value: 26 *7 * Sample options value:8 * {9 * "duration": 5,10 * "slotsAfter": 1,11 * "slotsBefore": 012 * }13 */1415timeSlots.getTimeSlots(reservationLocationId, new Date(date), partySize)16 .then((retrievedSlots) => {17 const firstStartDate = retrievedSlots.items[0].startDate;18 const firstStatus = retrievedSlots.items[0].status;1920 console.log('Success! Retrieved the following time slots:', retrievedSlots);21 return retrievedSlots;22 })23 .catch((error) => {24 console.error(error);25 // Handle the error26 });2728/* Promise resolves to:29* {30* "timeSlots": [31* {32* "startDate": "2023-12-29T12:30:00.000Z",33* "duration": 5,34* "status": "UNAVAILABLE",35* "tableCombinations": [],36* "manualApproval": false37* },38* {39* "startDate": "2023-12-29T12:45:00.000Z",40* "duration": 5,41* "status": "UNAVAILABLE",42* "tableCombinations": [],43* "manualApproval": false44* }45* ]46* }47*/48
1import { Permissions, webMethod } from 'wix-web-module';2import { timeSlots } from 'wix-table-reservations-v2';34/* Sample reservationLocationId value: 'fab8cc1f-31cf-462f-b5bb-392594624bf2'5 * Sample date value: new Date("2023-12-29T12:30:00Z")6 * Sample partySize value: 27 */89export const myGetTimeSlotsFunction = webMethod(Permissions.Anyone, async (options) => {10 try {11 const retrievedSlots = await timeSlots.getTimeSlots(reservationLocationId, new Date(date), partySize)1213 const firstStartDate = retrievedSlots.items[0].startDate;14 const firstStatus = retrievedSlots.items[0].status;1516 console.log('Success! Retrieved the following time slots:', retrievedSlots);17 return retrievedSlots;18 } catch (error) {19 console.error(error);20 // Handle the error21 }2223});2425/* Promise resolves to:26 * {27 * "timeSlots": [28 * {29 * "startDate": "2023-12-29T10:00:00.000Z",30 * "duration": 90,31 * "status": "AVAILABLE",32 * "tableCombinations": [33 * {34 * "tableIds": [35 * "1ed802ae-708f-4da6-9177-54c3df5d3dd5"36 * ]37 * }38 * ],39 * "manualApproval": false40 * },41 * {42 * "startDate": "2023-12-29T10:15:00.000Z",43 * "duration": 90,44 * "status": "AVAILABLE",45 * "tableCombinations": [46 * {47 * "tableIds": [48 * "1ed802ae-708f-4da6-9177-54c3df5d3dd5"49 * ]50 * }51 * ],52 * "manualApproval": false53 * },54 * {55 * "startDate": "2023-12-29T10:30:00.000Z",56 * "duration": 90,57 * "status": "AVAILABLE",58 * "tableCombinations": [59 * {60 * "tableIds": [61 * "1ed802ae-708f-4da6-9177-54c3df5d3dd5"62 * ]63 * }64 * ],65 * "manualApproval": false66 * },67 * {68 * "startDate": "2023-12-29T10:45:00.000Z",69 * "duration": 90,70 * "status": "AVAILABLE",71 * "tableCombinations": [72 * {73 * "tableIds": [74 * "1ed802ae-708f-4da6-9177-54c3df5d3dd5"75 * ]76 * }77 * ],78 * "manualApproval": false79 * },80 * {81 * "startDate": "2023-12-29T11:00:00.000Z",82 * "duration": 90,83 * "status": "AVAILABLE",84 * "tableCombinations": [85 * {86 * "tableIds": [87 * "1ed802ae-708f-4da6-9177-54c3df5d3dd5"88 * ]89 * }90 * ],91 * "manualApproval": false92 * },93 * {94 * "startDate": "2023-12-29T11:15:00.000Z",95 * "duration": 90,96 * "status": "UNAVAILABLE",97 * "tableCombinations": [],98 * "manualApproval": false99 * },100 * {101 * "startDate": "2023-12-29T11:30:00.000Z",102 * "duration": 90,103 * "status": "UNAVAILABLE",104 * "tableCombinations": [],105 * "manualApproval": false106 * },107 * {108 * "startDate": "2023-12-29T11:45:00.000Z",109 * "duration": 90,110 * "status": "UNAVAILABLE",111 * "tableCombinations": [],112 * "manualApproval": false113 * },114 * {115 * "startDate": "2023-12-29T12:00:00.000Z",116 * "duration": 90,117 * "status": "UNAVAILABLE",118 * "tableCombinations": [],119 * "manualApproval": false120 * },121 * {122 * "startDate": "2023-12-29T12:15:00.000Z",123 * "duration": 90,124 * "status": "UNAVAILABLE",125 * "tableCombinations": [],126 * "manualApproval": false127 * },128 * {129 * "startDate": "2023-12-29T12:30:00.000Z",130 * "duration": 90,131 * "status": "UNAVAILABLE",132 * "tableCombinations": [],133 * "manualApproval": false134 * },135 * {136 * "startDate": "2023-12-29T12:45:00.000Z",137 * "duration": 90,138 * "status": "UNAVAILABLE",139 * "tableCombinations": [],140 * "manualApproval": false141 * },142 * {143 * "startDate": "2023-12-29T13:00:00.000Z",144 * "duration": 90,145 * "status": "UNAVAILABLE",146 * "tableCombinations": [],147 * "manualApproval": false148 * },149 * {150 * "startDate": "2023-12-29T13:15:00.000Z",151 * "duration": 90,152 * "status": "UNAVAILABLE",153 * "tableCombinations": [],154 * "manualApproval": false155 * },156 * {157 * "startDate": "2023-12-29T13:30:00.000Z",158 * "duration": 90,159 * "status": "UNAVAILABLE",160 * "tableCombinations": [],161 * "manualApproval": false162 * },163 * {164 * "startDate": "2023-12-29T13:45:00.000Z",165 * "duration": 90,166 * "status": "UNAVAILABLE",167 * "tableCombinations": [],168 * "manualApproval": false169 * },170 * {171 * "startDate": "2023-12-29T14:00:00.000Z",172 * "duration": 90,173 * "status": "AVAILABLE",174 * "tableCombinations": [175 * {176 * "tableIds": [177 * "1ed802ae-708f-4da6-9177-54c3df5d3dd5"178 * ]179 * }180 * ],181 * "manualApproval": false182 * },183 * {184 * "startDate": "2023-12-29T14:15:00.000Z",185 * "duration": 90,186 * "status": "AVAILABLE",187 * "tableCombinations": [188 * {189 * "tableIds": [190 * "1ed802ae-708f-4da6-9177-54c3df5d3dd5"191 * ]192 * }193 * ],194 * "manualApproval": false195 * },196 * {197 * "startDate": "2023-12-29T14:30:00.000Z",198 * "duration": 90,199 * "status": "AVAILABLE",200 * "tableCombinations": [201 * {202 * "tableIds": [203 * "1ed802ae-708f-4da6-9177-54c3df5d3dd5"204 * ]205 * }206 * ],207 * "manualApproval": false208 * },209 * {210 * "startDate": "2023-12-29T14:45:00.000Z",211 * "duration": 90,212 * "status": "AVAILABLE",213 * "tableCombinations": [214 * {215 * "tableIds": [216 * "1ed802ae-708f-4da6-9177-54c3df5d3dd5"217 * ]218 * }219 * ],220 * "manualApproval": false221 * },222 * {223 * "startDate": "2023-12-29T15:00:00.000Z",224 * "duration": 90,225 * "status": "AVAILABLE",226 * "tableCombinations": [227 * {228 * "tableIds": [229 * "1ed802ae-708f-4da6-9177-54c3df5d3dd5"230 * ]231 * }232 * ],233 * "manualApproval": false234 * }235 * ]236 * }237 */
This scenario sets up an interface that allows a site owner to select a reservation location and a party size, then select a time slot to reserve. Once a time slot is selected, the site owner can click a confirm button to create a held reservation at that time.
1/* This example requires the following elements:2 * A dropdown element named `locationDropdown`.3 * A dropdown element named `partySizeDropdown`.4 * A dropdown element named `timeSlotDropdown`.5 * A button named `confirmButton`.6 * A text element named `heldReservationNotification`.7 */89/**********************************************10 * Backend code - reservationLocations.web.js *11 **********************************************/1213import { Permissions, webMethod } from 'wix-web-module';14import { locations } from 'wix-business-tools.v2';15import { elevate } from 'wix-auth';1617export const getRestaurantLocation = webMethod(Permissions.Anyone, async (location_id) => {18 const elevatedGetLocation = elevate(locations.getLocation);1920 try {21 const result = await elevatedGetLocation(location_id);22 return result;23 } catch (error) {24 console.error(error);25 // Handle the error26 }27});2829/*************30 * Page code *31 *************/3233import { reservationLocations } from 'wix-table-reservations.v2';34import { reservations } from 'wix-table-reservations.v2';35import { timeSlots } from 'wix-table-reservations.v2';3637import { getRestaurantLocation } from 'backend/reservationLocations.web';3839$w.onReady(async function () {40 $w('#timeSlotDropdown').hide();41 $w('#partySizeDropdown').hide();42 $w('#confirmButton').hide();43 $w('#heldReservationNotification').hide();4445 //Get the list of reservation locations46 const myReservationLocationList = await (async () => {47 try {48 let fullListObject = await reservationLocations.listReservationLocations();49 return fullListObject.reservationLocations;50 } catch (error) {51 console.error(error);52 // Handle the error53 }54 })();5556 //Create an array to hold names and values for our locations dropdown list57 let locationDropdownOptions = [];58 for (const object in myReservationLocationList){59 //Use the _id stored in the reservation location's location object to get the location's name from the `locations` service60 const locationObject = await getRestaurantLocation(myReservationLocationList[object].location._id);61 locationDropdownOptions.push({62 "label": locationObject.name,63 "value": myReservationLocationList[object]._id64 })65 }66 //Populate our dropdown list with the array67 $w("#locationDropdown").options = locationDropdownOptions;6869 //Create an array to hold numbers and values for our party size dropdown list70 let partySizeDropdownOptions = [];71 for (let i = 1; i<10; i++){72 partySizeDropdownOptions.push({73 "label": String(i),74 "value": String(i)75 })76 }77 //Populate our dropdown list with the array78 $w("#partySizeDropdown").options = partySizeDropdownOptions;7980 $w('#locationDropdown').onChange( (event) => {81 if ($w('#locationDropdown').value) {82 $w('#partySizeDropdown').show();83 $w('#timeSlotDropdown').hide()84 $w('#confirmButton').hide();85 }86 });8788 $w('#partySizeDropdown').onChange( async (event) => {89 if ($w('#locationDropdown').value) {90 $w('#timeSlotDropdown').show()91 $w('#confirmButton').hide();9293 const timeSlotDetails = {94 "reservationLocationId": $w('#locationDropdown').value,95 "date": new Date(),96 "partySize": parseInt($w('#partySizeDropdown').value)97 };9899 const timeSlotOptions = {100 "duration": 30,101 "slotsAfter": 8,102 "slotsBefore": 0103 };104105 //Get the list of time slots according to the details and options above106 const availableTimeSlots = await (async () => {107 try {108 let fullListObject = await timeSlots.getTimeSlots(timeSlotDetails.reservationLocationId, timeSlotDetails.date, timeSlotDetails.partySize, timeSlotOptions);109 return fullListObject.timeSlots;110 } catch (error) {111 console.error(error);112 // Handle the error113 }114 })();115116 //Create an array to hold numbers and values for our time slot dropdown list117 let timeSlotDropdownOptions = [];118 for (const timeSlot in availableTimeSlots){119 if(availableTimeSlots[timeSlot].status == "AVAILABLE"){120 timeSlotDropdownOptions.push({121 "label": String(availableTimeSlots[timeSlot].startDate),122 "value": String(availableTimeSlots[timeSlot].startDate)123 })124 }125 }126 //Populate our dropdown list with the array127 $w("#timeSlotDropdown").options = timeSlotDropdownOptions;128 }129 });130131 $w('#timeSlotDropdown').onChange( async (event) => {132 if ($w('#timeSlotDropdown').value) {133 $w('#confirmButton').show();134 }135 });136137 $w('#confirmButton').onClick( async (event) => {138 //Get the list of time slots according to the details and options above139140 const createdHeldReservation = await (async () => {141 try {142 const reservationDetails = {143 "reservationLocationId": $w('#locationDropdown').value,144 "startDate": new Date($w("#timeSlotDropdown").value),145 "partySize": parseInt($w('#partySizeDropdown').value)146 };147148 return await reservations.createHeldReservation(reservationDetails);149 } catch (error) {150 console.error(error);151 // Handle the error152 }153 })();154155 if(createdHeldReservation){156 $w('#heldReservationNotification').text = "Held reservation created successfully."157 $w('#heldReservationNotification').show();158 }159 });160});161