[SalesForce] LWC best Practice to call parent and child component

My question is bit difficult to explain but still I tried my best to explain it in the below playground

Playground

In my LWC project I have 3 step process and I divided it into 3 lwc pages

  1. parent
  2. child
  3. grandchild

Now as shown in the above playground on a click of a button I change flags and display the pages accordingly, in real time I am saving and retrieving data from the page in all three steps and I also have spinners on each page so that when data is coming and going to apex a spinner will appear.

The above structure works as expected but when data iterated on the page increased and if I click go to child button then it take 3 to 4 seconds of time to display the child page and coming back to parent takes even more time even though I am checking flags to show spinner(didn't add spinner on playground) but spinner comes only when a page is loaded and waiting from apex to retrieve the data from the database.

Even if buttons take time to respond at least a spinner should appear but the same is not happening.

Now my request is to please confirm if the above structure to show a three steps process is as per best practice or is there any better approach to display 3 LWC pages step wise step on click of a button as shown in the playground and if the button is taking 3 4 seconds of time to respond then how can I show the spinner on that period of time.

ADDED

In the next button If I write like below

nextPage = () => { this.showSpinner = true; this.step++; this.showSpinner = false; }

button takes 7 to 8 seconds to switch page but still no spinner comes

and if I change the button like below

 nextPage = () => { this.showSpinner = true; this.step++; }

Still spinner comes after 7 to 8 seconds, could you please suggest how can I cover the waiting time with spinner?

Best Answer

The only reason spinner may not be showing up is because your javascript calculations (like this counting code) before switching page is taking 3-4 seconds. You need to check for such calculations.

Regarding the best practices, whether its 3 pages or 10 pages, what you are trying to implement is known as wizard and you can keep the code simple, maintainable and uniform by having only 2 buttons in the container page html and relevant JS. Below is the sample container code: (Playground Link)

<div>
    <div>
        <template if:true={show1Step}>
            <c-parent full-data={fullData}></c-parent>
        </template>
        <template if:true={show2Step}>
            <c-child full-data={fullData}></c-child>
        </template>
        <template if:true={show3Step}>
            <c-grandchild full-data={fullData}></c-grandchild>
        </template>
    </div>

    <!-- BUTTONS -->
    <template if:false={show1Step}>
        <lightning-button label={prevLabel} 
                            class="slds-float_left"
                            onclick={prevPage}>
        </lightning-button>
    </template>
    <template if:false={show3Step}>
        <lightning-button label={nextLabel} 
                            class="slds-float_right"
                            onclick={nextPage}>
        </lightning-button>
    </template>
</div>

JS:

export default class App extends LightningElement {
    @track fullData;
    @track step = 1;

    nextPage = () => this.step++;
    prevPage = () => this.step--;

    get show1Step() { return this.step === 1; }
    get show2Step() { return this.step === 2; }
    get show3Step() { return this.step === 3; }

    get nextLabel() {
        if (this.show1Step) return 'Go To Child';
        else if (this.show2Step) return 'Go To Grand Child';
        else return 'Next';
    }
    get prevLabel() {
        if (this.show2Step) return 'Go To Parent';
        else if (this.show3Step) return 'Go To Child';
        else return 'Previous';
    }
}

added

In LWC you cannot change the data passed in api variables - so you cannot change the data in child components. You need to send the changed data in event to container component which will take care of modifying the fullData which will in-turn reflect in all child components and thus showing the latest data in all child components.

Here is the reference

A component that declares a public property can set only its default value. A parent component that uses the component in its markup can set the component’s public property value. In our example, the c-todo-item component can’t update the value of the itemName property in the todoItem.js file.

Related Topic