0

I have a template tag with if:true attribute at the top level of my html file. When the page first renders, the content can be displayed normally. However, after clicking the refresh button I would like to hide the content by changing the ready variable to false, but the whole component is still rendered in spite of that.

Here is the html template:

<template>
<template if:true={ready}>
    <lightning-layout>
        <lightning-layout-item padding="around-small">
            <lightning-button variant="brand" label="Refresh" onclick={handleRefreshView}></lightning-button>
        </lightning-layout-item>
    </lightning-layout>
    <br/>
    <template for:each={reportItems} for:item="contractType" for:index="i">
        <table key={contractType.contractName} class="slds-table slds-table_cell-buffer slds-table_bordered slds-table_col-bordered slds-table_striped slds-no-row-hover">
            <thead align="center">
                <tr class="slds-line-height_reset">
                    <th>NPV Analysis ({contractType.contractLabel})</th>
                    <template for:each={contractType.products} for:item="item" for:index="index">
                        <th key={item.productName} colspan="5">{item.productName}</th>
                    </template>
                    <th rowspan="2">Total</th>
                </tr>
                <tr class="slds-line-height_reset">
                    <th></th>
                    <template for:each={contractType.products} for:item="item">
                        <th key={item.productName}>Year 0</th>
                        <th key={item.productName}>Year 1</th>
                        <th key={item.productName}>Year 2</th>
                        <th key={item.productName}>Year 3</th>
                        <th key={item.productName}>Total</th>
                    </template>
                </tr>
            </thead>
            <tbody>
               //... table content
            </tbody>
        </table>
    </template>
</template>
</template>

Controller:

import { LightningElement, track, api, wire } from 'lwc';
import retrievePricingItemsNPV from '@salesforce/apex/HGC_BCS01_BCaseController.retrievePricingItemsNPV';

export default class BCaseNPV extends LightningElement {

    @api bCaseId;
    @track ready = false;
    wiredPricingItemsResult;

    @wire(retrievePricingItemsNPV, { bCaseId: '$bCaseId'})
    handlePricingReport(result) {
        this.wiredPricingItemsResult = result;
        if(result.data) {
            this.reportItems = result.data;
            this.ready = true; // Template can be rendered
        } else if(result.error) {
            console.error(result.error);
        }
    }

    handleRefreshView() {
        this.ready = false; // Template is not hidden
    }

}

I suspect that having nested for:each tag might have something to do with it. Also some for:each tags have multiple children which is not assigned a unique key yet, I'm not sure if this is related to the issue.

Any advice would be appreciated!

4
  • 1
    Have you tried a console.log inside handleRefreshView to see if it is really invoked by the button? Apr 9, 2020 at 9:30
  • It is also possible that the data and window refresh are done in one and the same event. That at the first opportunity for the window to refresh, the data has already been fetched and ready is true again. Apr 9, 2020 at 10:00
  • @SanderdeJong That's exactly it; the wire method would be called again (using cached data), so it immediately flips back to true.
    – sfdcfox
    Apr 9, 2020 at 15:24
  • @sfdcfox I have put a breakpoint inside the wire method and I can confirm that the wire method is not called at any point after the page renders.
    – gbw939
    Apr 14, 2020 at 3:06

2 Answers 2

1

There are two things i don't see here. 1. this.reportItems is not in your sample 2. You are always setting it to true, versus setting to false if you have no report items.

I have made a small modification to the code here to handle setting the value to false based on the reportItems from your wire method, and added the reportItems variable in here.

import { LightningElement, track, api, wire } from 'lwc';
import retrievePricingItemsNPV from '@salesforce/apex/HGC_BCS01_BCaseController.retrievePricingItemsNPV';

export default class BCaseNPV extends LightningElement {

    @api bCaseId;
    @track reportItems = [];
    @track ready = false;
    wiredPricingItemsResult;

    @wire(retrievePricingItemsNPV, { bCaseId: '$bCaseId'})
    handlePricingReport({ error, result }) {
        this.wiredPricingItemsResult = result;
        if(result ) {
            this.reportItems = result.data ?  [ ...result.data ] : [];
            this.ready = this.reportItems && Array.isArray( this.reportItems ) && this.reportItems.length > 0;
        } else if(result.error) {
            console.error(result.error);
            this.ready = false;
        }
    }

    handleRefreshView() {
        this.ready = false; // Template is not hidden
    }

}

Hope this helps get you on your way.

0

I have fixed this problem by adding another condition denoted by if:false={ready}.

Without the false condition the items are rendered regardless of the boolean flag, but once I add it then it works as expected!

The final template is as follows:

<template>
<template if:true={ready}>
    <lightning-layout>
        <lightning-layout-item padding="around-small">
            <lightning-button variant="brand" label="Refresh" onclick={handleRefreshView}></lightning-button>
        </lightning-layout-item>
    </lightning-layout>
    <br/>
    <template for:each={reportItems} for:item="contractType" for:index="i">
        <table key={contractType.contractName} class="slds-table slds-table_cell-buffer slds-table_bordered slds-table_col-bordered slds-table_striped slds-no-row-hover">
            <thead align="center">
                <tr class="slds-line-height_reset">
                    <th>NPV Analysis ({contractType.contractLabel})</th>
                    <template for:each={contractType.products} for:item="item" for:index="index">
                        <th key={item.productName} colspan="5">{item.productName}</th>
                    </template>
                    <th rowspan="2">Total</th>
                </tr>
                <tr class="slds-line-height_reset">
                    <th></th>
                    <template for:each={contractType.products} for:item="item">
                        <th key={item.productName}>Year 0</th>
                        <th key={item.productName}>Year 1</th>
                        <th key={item.productName}>Year 2</th>
                        <th key={item.productName}>Year 3</th>
                        <th key={item.productName}>Total</th>
                    </template>
                </tr>
            </thead>
            <tbody>
               //... table content
            </tbody>
        </table>
    </template>
</template>
<template if:false={ready}>
   <!-- Display if not ready -->
</template>
</template>

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .