0

I'm trying to display content of an array as I loop through it in HTML of an LWC.

js:

import { LightningElement, track, wire } from 'lwc';
import getAvailableProperties from '@salesforce/apex/PropertyController.getAvailableProperties';
import getAvailableBookingSlots from '@salesforce/apex/PropertyController.getAvailableBookingSlots';
import createBooking from '@salesforce/apex/PropertyController.createBooking';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { refreshApex } from '@salesforce/apex';

export default class PropertyBooking extends LightningElement {
    @track selectedProperty;
    @track selectedSlot;
    @track error;
    @track slots = [];

    @wire(getAvailableProperties) properties;

    @wire(getAvailableBookingSlots, { propertyId: '$selectedProperty' })
    wiredSlots({ data, error }) {
        if (data) {
            //this.slots = data;
            for (let i=0; i < data.length; i++) {
                /* console.log('slot start ****  ', JSON.stringify(data[i].start));
                console.log('slot end ****  ', JSON.stringify(data[i].end)); */
                this.slots[i] = data[i].start + ' to ' + data[i].end;
            }
            console.log('this.slots ------- ', JSON.stringify(this.slots));
            this.error = undefined;
        } else if (error) {
            this.error = error;
            this.slots = [];
        }
    }

    get propertyOptions() {
        return this.properties.data ? this.properties.data.map(property => {
            return { label: property.Name, value: property.Id };
        }) : [];
    }

    handlePropertyChange(event) {
        this.selectedProperty = event.detail.value;
        this.selectedSlot = null; // Reset selected slot when changing property
    }

    handleSlotSelection(event) {
        this.selectedSlot = event.target.dataset.slot;
    }

    handleBooking() {
        if (this.selectedProperty && this.selectedSlot) {
            const slot = this.slots[parseInt(this.selectedSlot)];
            const startDate = new Date(slot.start);
            const endDate = new Date(slot.end);

            createBooking({ propertyId: this.selectedProperty, startDate: startDate, endDate: endDate })
                .then(result => {
                    this.dispatchEvent(
                        new ShowToastEvent({
                            title: 'Booking Status',
                            message: result,
                            variant: result.includes('successfully') ? 'success' : 'error',
                        })
                    );
                    if (result.includes('successfully')) {
                        // Refresh the available properties and slots
                        return refreshApex(this.properties) && refreshApex(this.wiredSlots);
                    }
                })
                .catch(error => {
                    this.error = error;
                    this.dispatchEvent(
                        new ShowToastEvent({
                            title: 'Error creating booking',
                            message: error.body.message,
                            variant: 'error',
                        })
                    );
                });
        } else {
            this.dispatchEvent(
                new ShowToastEvent({
                    title: 'Missing Information',
                    message: 'Please select a property and a date range to book.',
                    variant: 'warning',
                })
            );
        }
    }
}

Console looks like this:

this.slots -------  ["2024-06-08 to 2024-06-15","2024-06-15 to 2024-06-22","2024-06-22 to 2024-06-29","2024-06-29 to 2024-07-06","2024-07-06 to 2024-07-13","2024-07-13 to 2024-07-20","2024-07-20 to 2024-07-27","2024-07-27 to 2024-08-03","2024-08-03 to 2024-08-10","2024-08-31 to 2024-09-07","2024-09-07 to 2024-09-14","2024-09-14 to 2024-09-21","2024-09-21 to 2024-09-28","2024-09-28 to 2024-10-05","2025-06-08 to 2025-06-15","2025-06-15 to 2025-06-22","2025-06-22 to 2025-06-29","2025-06-29 to 2025-07-06","2025-07-06 to 2025-07-13","2025-07-13 to 2025-07-20","2025-07-20 to 2025-07-27","2025-07-27 to 2025-08-03","2025-08-03 to 2025-08-10","2025-08-10 to 2025-08-17","2025-08-17 to 2025-08-24","2025-08-24 to 2025-08-31","2025-08-31 to 2025-09-07","2025-09-07 to 2025-09-14","2025-09-14 to 2025-09-21","2025-09-21 to 2025-09-28","2025-09-28 to 2025-10-05"]

HTML for:each:

            <template for:each={slots} for:item="slot" for:index="index">
                {slot}
                <li key={slot} class="slds-m-bottom_xx-small">
                    <lightning-button
                        label='book'
                        onclick={handleSlotSelection}
                        data-slot={index}
                        class='slds-button_brand'>
                    </lightning-button>
                </li>
            </template>

I can't get the slot text to appear on the page.

Any suggestions appreciated.

2
  • 1
    where and how is slots declared? Please edit your question to include this information. Commented Aug 6, 2024 at 1:35
  • @NickC - I added the JS file Commented Aug 6, 2024 at 12:42

1 Answer 1

1

I have tried your code in my org. I have set the static slot data and tried to render it into the HTML of LWC.

HTML:

<template>
      <template if:true={slots}>
            <ul>
                <template for:each={slots} for:item="slot" for:index="index">
                    <li key={slot} class="slds-m-bottom_xx-small">
                        {slot}
                        <lightning-button label="book" onclick={handleSlotSelection} data-slot={index}
                            class="slds-button_brand">
                        </lightning-button>
                    </li>
                </template>
            </ul>
        </template>
        <template if:true={error}>
            <p>{error}</p>
        </template>
</template>

JS:

import { LightningElement, api, track, wire } from 'lwc';
export default class Test extends LightningElement {
    @track slots = ["2024-06-08 to 2024-06-15","2024-06-15 to 2024-06-22","2024-06-22 to 2024-06-29","2024-06-29 to 2024-07-06","2024-07-06 to 2024-07-13","2024-07-13 to 2024-07-20","2024-07-20 to 2024-07-27","2024-07-27 to 2024-08-03","2024-08-03 to 2024-08-10","2024-08-31 to 2024-09-07","2024-09-07 to 2024-09-14","2024-09-14 to 2024-09-21","2024-09-21 to 2024-09-28","2024-09-28 to 2024-10-05","2025-06-08 to 2025-06-15","2025-06-15 to 2025-06-22","2025-06-22 to 2025-06-29","2025-06-29 to 2025-07-06","2025-07-06 to 2025-07-13","2025-07-13 to 2025-07-20","2025-07-20 to 2025-07-27","2025-07-27 to 2025-08-03","2025-08-03 to 2025-08-10","2025-08-10 to 2025-08-17","2025-08-17 to 2025-08-24","2025-08-24 to 2025-08-31","2025-08-31 to 2025-09-07","2025-09-07 to 2025-09-14","2025-09-14 to 2025-09-21","2025-09-21 to 2025-09-28","2025-09-28 to 2025-10-05"];
    @track error;
}

Output: enter image description here

4
  • Thanks @Tushar_Jadav - slots has a value and I still don't see it on the page. Could it have something to do with it being displayed in Experience Cloud? Commented Aug 6, 2024 at 13:07
  • When I hard-code slots, it shows on the page. I need to be able to get the slots from the backend though. What could be going on where I don't see it when I retrieve from code? Commented Aug 6, 2024 at 13:12
  • @mackmama, You need to give permission to the community User to access the LWC and Its Apex Controller. Also the Object and its fields. Commented Aug 6, 2024 at 13:15
  • 1
    Thanks - forgot about granting access to the custom objects. That did it. Commented Aug 6, 2024 at 15:02

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.