5

(1) I have a Lightning Component Tab on which sits a Lightning Web Component.

(2) I navigate to the tab WITH CONTEXT using the NavigationMixin from other LWC components elsewhere in the application.

(3) So the URL when I navigate to the tab/lwc looks like this:

 https://revdev1-dev-ed.lightning.force.com/lightning/n/Freight_Plan_Console?c__loadId=a0r1U00000600mNQAQ

Note the context parameter c__loadId. This value of course changes based on the Load (page) I am coming from.

Here is my issue:

(1) The first time the tab is navigated to everything works fine -- The constructor, connectedCallback and @wire functions all execute and build the component. I am able to capture the URL parameters and act on them.

(2) However, subsequent navigation to the tab with a different load context does not work. The LWC is cached somewhere and so the functions above are not re-invoked.

(3) This is a problem as the URL context parameter has changed and I need to execute logic to deal with the change.

(4) Note that if I navigate around a lot or browser-refresh a page the LWC will rebuild itself correctly. But of course we cannot rely on that.

Another way to pose the question: When you navigate away from and then back to a Tab with an LWC on it, what hook can I use to execute code each time the LWC/tab is returned to?

Another way to pose the question: How do I guarantee an LWC is rebuilt each time it is navigated to?

Thanks!

Adding navigation code to LWC Tab:

addFreightPlanHandler() {

    let namespace = LightningUtil.getNamespace();
    let cnamespace = namespace ? namespace : 'c__';
    let state = {};
    state[cnamespace + 'loadId'] = this.load.Id.value;

    this[NavigationMixin.Navigate]({ type: 'standard__navItemPage', 
                                     attributes: { apiName: namespace + 'Freight_Plan_Console' },
                                     state: state });                
}

Adding first part of LWC that we are navigating to. Nothing unique about it that I am aware of:

    <template>
        <lightning-layout multiple-rows="false">
            <!-- FILTER/TEMPLATE PANEL -->
            <template if:true={showFilterTemplatePanel}>
                <lightning-layout-item size="3">
                    <div class="slds-card">
                        <div class="panelSpacer">
    .....
6
  • have you tried adding a console log to a rendered callback/connected callback/etc. to see if any of them are called when you navigate back to the tab? Commented Nov 18, 2021 at 18:06
  • Yes I have and nothing is re-executed.
    – Dave C
    Commented Nov 18, 2021 at 19:26
  • 2
    can you share your code for the LWC which is inside the tab?
    – User6670
    Commented Nov 24, 2021 at 16:56
  • Does this Q&A help? Also, are you always using PageReferences/navigation events to update the query string of the URL?
    – nbrown
    Commented Nov 24, 2021 at 17:17
  • Thanks for trying to help, folks. Code added above. The navigation code works fine - the first time. Nothing unique about the control that is contributing to this issue.
    – Dave C
    Commented Nov 26, 2021 at 13:08

3 Answers 3

5
+50

We had a similar cache issue in the past and managed to resolve it using @wire(CurrentPageReference) and getter/setter methods instead of connectedCallback. [as @nbrown pointed out in the comments]

Reference docs :

The connectedCallback() hook is invoked with the initial properties passed to the component. If a component derives its internal state from the properties, it's better to write the logic in a setter than in connectedCallback()

@wire(CurrentPageReference) captures the updated parameter state each time the page is loaded, then you can invoke your custom logic based on the new state parameter value.

Here's some sample code to get you started using CurrentPageReference

LWC componnent tab

HTML

<template>
    <div class="slds-grid slds-theme_default slds-box">
        <div class="slds-col slds-size_4-of-12">
            <h2 class="slds-text-heading_small slds-var-m-bottom_medium">
                Load Id : <code> {loadId}</code> 
            </h2>
        </div>
        <div class="slds-col slds-size_8-of-12" if:true={objectApiName}>
            <lightning-record-view-form
                object-api-name={objectApiName}
                record-id={loadId}>
            <div class="slds-box">
                <lightning-output-field field-name="Name"> </lightning-output-field>
            </div>
            </lightning-record-view-form>
        </div>
    </div>
</template>

JS

import { LightningElement,api, wire, track } from 'lwc';
import { CurrentPageReference, NavigationMixin } from 'lightning/navigation';

export default class LwcCustomTab extends NavigationMixin(LightningElement) {
    currentPageReference;
    @api loadId;
    @api objectApiName;

    @wire(CurrentPageReference)
    getCurrentPageReference(currentPageReference) {
        this.currentPageReference = currentPageReference;
        //show spinner if processing is long
        new Promise(
            (resolve, reject) => {
            setTimeout(() => {
                if(this.currentPageReference){
                    this.loadId = this.currentPageReference.state.c__loadId 
                                ? this.currentPageReference.state.c__loadId : null;
                    this.objectApiName = this.currentPageReference.state.c__objectApiName 
                                ? this.currentPageReference.state.c__objectApiName : null;
                    //perform additional logic with new loadId
                    resolve();
                }
            }, 0);
            })                
            .catch((error) => {
                console.error(JSON.stringify(error));
            })
            .finally(() => {
                // disable a spinner if applicable
            }); 
    }
}

XML

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>53.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__Tab</target>
    </targets>
</LightningComponentBundle>

LWC redirecting to custom tab

HTML

<template>
    <div class="slds-grid slds-theme_default slds-box">
        <div class="slds-col"></div>
        <div class="slds-col">
            <lightning-button label="Redirect To Tab" variant="brand" 
                onclick={navigateToCustomTab} ></lightning-button>
        </div>
    </div>
</template>

JS

import { LightningElement, api } from 'lwc';
import { NavigationMixin } from 'lightning/navigation';

export default class LwcNavigateToTab extends NavigationMixin(LightningElement) {

    @api loadId;
    @api recordId;
    @api objectApiName;

    navigateToCustomTab(){
        this[NavigationMixin.Navigate]({
            type: 'standard__navItemPage',
            attributes: {
                apiName: 'LWC_Custom_Tab'
            },
            state: {
                c__loadId : this.recordId ? this.recordId : this.loadId,
                c__objectApiName : this.objectApiName
            }
        });
    }
}

XML

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>53.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__RecordPage</target>
        <target>lightning__AppPage</target>
        <target>lightning__HomePage</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="lightning__RecordPage,lightning__AppPage,lightning__HomePage">
            <property name="loadId" label="Custom Load Id" type="String" />
            <property name="objectApiName" label="Object API Name" type="String" />
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>
2
  • Exactly what I needed, Shamina. Thank you!! And thank you to the others who helped with comments.
    – Dave C
    Commented Nov 29, 2021 at 18:19
  • @DaveC Good to know this helps 👍
    – Shamina
    Commented Nov 30, 2021 at 5:31
1

This was a common problem with Aura Components, so I assume the solution will be similar - you need to force refresh on pageReference change. Lightning navigation does not refresh the state of components, how to fix a bug

In LWC, change handlers are a little different than Aura, so you'll need to write a custom getter and setter for pageReference (the setter will force refresh the page aka run your init method again). This page talks about using CurrentPageReference in LWC: Invoking LWC component from a plain URL - Read URL Parameter inside LWC

If you can't get the change handler to work with the LWC, you can always wrap the LWC in an Aura Component and force the refresh by using the Aura strategy in the first link and calling the init method from the child LWC when the Aura Component detects the pageReference change.

1
  • Thanks, Benjamin.
    – Dave C
    Commented Dec 1, 2021 at 20:00
0

I don’t know, maybe I did something wrong. But nothing was working for my case. I had an LWC on the record detail page. It remained in the DOM when I navigated from the detail page to the list views or another tab within the application. But I needed it to work only on the detail page, because in other case the user kept receiving toast events.

CurrentPageReference didn’t change the reference on url update. Wrapping the LWC in Aura and using different handlers didn’t help either.

In the end, I used window.location.href to check the current url when processing the toast.

You must log in to answer this question.

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