4

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?

7

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.

| improve this answer | |
  • Thank you so much for this wonderful example but could you please confirm few things in your example you assign full data to all 3 pages at once but what if I change any thing on full data at first page then will the same reflect at the 2nd page and if I change full data again on 2nd page then full data will be change for 1st and 3rd page or just 3rd page or none. – gs650x Dec 8 '19 at 11:28
  • added in answer the correct way – salesforce-sas Dec 8 '19 at 12:13
  • Thank you so much, will try to implement the same in my project – gs650x Dec 8 '19 at 12:59
  • I re structured my LWC project as per your suggestion above thank you so much for this wonderful idea, I am using refresh apex to avoid the stale data and it was working as expected in previous structure but now when I update data on 1st page click on next page and come back to first page again I see older data instead of the updated one I added console logs and I can see the updated data in console log but I really wonder from it is getting the staled data, could you please suggest on it? – gs650x Dec 9 '19 at 8:47
  • 1
    @AtlasCan, yes right. – salesforce-sas Dec 11 '19 at 6:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.