Hi there,
I’m trying to display the available spots of each service displayed in a repeater. Everything works, however the value returned for “available spots” is always “undefined” and I don’t understand why… Can anyone help me?
Here’s an example of the value returned:
Here is my code:
//-------------Imports-------------//
import wixData from "wix-data";
import wixBookings from "wix-bookings";
// Map of services.
let servicesMap = {};
// List of services.
let services = [];
$w.onReady(() => {
setupRepeater();
setupButtons();
initializeSlots();
const today = new Date();
const endOfDay = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 23, 59, 59);
populateServicesSlots(today, endOfDay);
});
function showLoader(show = false) {
if (show === false) {
$w("#servicesLoader").hide();
} else {
$w("#servicesLoader").show();
}
}
async function initializeSlots() {
// Set the global services list to all the services of type class from the Services collection.
services = await getAllClasses();
// Put the services in a map for easy access by ID.
services.forEach(service => (servicesMap[service._id] = service));
}
async function populateServicesSlots(startDateTime, endDateTime) {
// Get the available slots from all the services for the given date range.
let availableSlots = await getMultipleServicesAvailability(services, {
startDateTime,
endDateTime,
});
// Sort the available slots in ascending order by start time.
availableSlots = availableSlots.sort((a, b) => a.startDateTime - b.startDateTime);
// Set the slot repeater's data to the sorted available slots, thereby populating the repeater.
$w("#servicesRepeater").data = availableSlots;
}
//-------------Bookings Data Retrieval-------------//
// Get all services of type class from the Services collection.
async function getAllClasses() {
const data = await wixData.query("Bookings/Services").eq("serviceType", "CLASS").find();
return data.items;
}
// Get the availability of multiple given services for the given date range. Optimize the service availability
// requests by batching all the service availability requests into one promise.
async function getMultipleServicesAvailability(requestedServices, availabilityOptions) {
// Create an empty list of Promises.
let slotsPromises = [];
// Create an empty list of slots.
let slots = [];
// For each of the given requested services:
requestedServices.forEach((requestedservice) => {
// Make a call to get the service's available slots and store the function's returned Promise.
const slotsPromise = wixBookings
.getServiceAvailability(requestedservice._id, availabilityOptions)
.then((result) => {
// When the Promise is resolved, add the available slots to the global slot list.
result.slots.forEach((slot) => slots.push(slot));
});
// Add the service availability Promise to the list of Promises.
slotsPromises.push(slotsPromise);
});
// Wait for all the availability calls for all the services to finish.
await Promise.all(slotsPromises);
// Return the available slots found from all the services.
return slots;
}
//-------------Repeater Setup-------------//
export function setupRepeater() {
// Set up each item in the services repeater as it is loaded. Note that
// most of the repeater elements are populated using a dataset.
$w("#servicesRepeater").onItemReady(async ($item, itemData, index) => {
if (index === 0) {
showLoader(false);
}
// Get the item's service ID.
const serviceId = itemData._id;
// Retrieve the available slots for the item's service.
const availability = await wixBookings.getServiceAvailability(serviceId);
// Store the first available slot as the next available slot.
const nextAvailableSlot = availability.slots[0];
// If there is an available slot:
if (nextAvailableSlot) {
// Set the nextSlot text to the month and day of the next available slot.
$item("#nextSlot").text = "Commence le " + getMonthDay(nextAvailableSlot.startDateTime);
$item("#availableSpots").text = itemData.remainingSpots + " places restantes";
}
// If there are no available slots:
else {
// Set the nextSlot text to ???.
$item("#nextSlot").text = "???";
}
});
}
//-------------Category Button Clicks-------------//
function setupButtons() {
// Filter the displayed services using the "ALL" button.
$w("#allButton").onClick((event) => {
// Reset the filter to show all services
const allQuery = wixData.filter();
// Set the active category to "All"
setActiveCategory("All", allQuery);
// Scroll the page to the list of services.
scrollToServiceStrip();
});
// Filter the displayed services using the "THERMO" button.
$w("#thermoButton").onClick((event) => {
// Create a filter that filters services by "Thermopompe murale" serviceName.
const thermoQuery = wixData.filter().eq("serviceName", "Thermopompes murales");
// Set the active category to "Thermopompe murale"
setActiveCategory("Thermopompes murales", thermoQuery);
// Scroll the page to the list of services.
scrollToServiceStrip();
});
// Filter the displayed services using the "RESIDENTIAL" button.
$w("#residentialButton").onClick((event) => {
// Create a filter that filters services by "Systèmes et conduits résidentiels" serviceName.
const residentialQuery = wixData.filter().eq("serviceName", "Systèmes et conduits résidentiels");
// Set the active category to "Systèmes et conduits résidentiels"
setActiveCategory("Systèmes et conduits résidentiels", residentialQuery);
// Scroll the page to the list of services.
scrollToServiceStrip();
});
// Filter the displayed services using the "COMMERCIAL" button.
$w("#commercialButton").onClick((event) => {
// Create a filter that filters services by "Systèmes et conduits commerciaux" serviceName.
const commercialQuery = wixData.filter().eq("serviceName", "Systèmes et conduits commerciaux");
// Set the active category to "Systèmes et conduits commerciaux"
setActiveCategory("Systèmes et conduits commerciaux", commercialQuery);
// Scroll the page to the list of services.
scrollToServiceStrip();
});
}
//-------------Change Category-------------//
// Set the category of services to display.
async function setActiveCategory(title, queryFilter) {
$w("#servicesRepeater").data = [];
// Populate the title text with the given title.
$w("#stripTitle").text = title;
showLoader(true);
// Filter the dataset using the given filter.
await $w("#dataset1").setFilter(queryFilter);
}
// Scroll down to the displayed services.
function scrollToServiceStrip() {
$w("#servicesStrip").scrollTo();
}
//-------------Date Helpers-------------//
// Get the month and day of the given date formatted as DD/MM.
function getMonthDay(date) {
return date.toLocaleDateString([], { day: "numeric", month: "numeric" });
}
Merci à l’avance pour votre aide !