[SalesForce] LWC template if:true not hiding content when false

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!

Best Answer

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.

Related Topic