0

I have a parent LWC component componentP where I have used Tabset and under that I have different Tabs.

For TabA I have a componentA from where I am updating/ inserting the records in ObjectA, and for updating I am using a apex controllerA. Now, once the insertion is done, when I switch to TabB I don't see the refreshed / latest data entered in my table. For TabB I am using componentB , and I am using apex componentB to fetch those records.

So, I want to know, once I save the record from TabA why it's not showing the latest details in TabB. How can I do that? I have tried refreshApex, using @wire and AuraEnabled(cacheable=true) to fetch the records, but it's not working.

Here's the code for your reference. When The page loaded it should display the presernt data in object, also when any new record is inserted it should automatically show the data without page load.

1.a. paremt componentP HTML

<template>
    <lightning-tabset variant="Scoped">
    <lightning-tab label="TabA" onactive={handleActive}>
            <c-component-a saved-stories={savedStories} tab-label={tabLabel} onsavedrecord={confirmation}></c-component-a>
        </lightning-tab>
       
        <lightning-tab label="TabB" onactive={handleActive}>
            <c-component-b saved-stories={savedStories} got-confirmation={gotConfirmation}></c-component-b>
        </lightning-tab>
    </lightning-tabset>
</template>

1.b Parent JS:

{
    handleActive(event){
        this.tabLabel = event.target.label;
        let component;
        switch(this.tabLabel){            
            case 'TabA':
                component = this.template.querySelector('c-component-a');
                break;
            case 'TabB':
                component = this.template.querySelector('c-component-b');
                break;
        }
        setTimeout(()=>{
            component.refreshData();
        },0);
    }
    
    gotConfirmation;
    confirmation(event){
         this.gotConfirmation = event.detail;
    }
}
  1. LWC componentA
    import { LightningElement,api,track} from 'lwc';
    import saveRecordOnClick from '@salesforce/apex/SDLC_DesignController.saveRecordOnClick';
    export default class ComponentA extends LightningElement {
    
      isSaved=false;
        saveComponentSpec(){
            this.isSaved =true;
            console.log('Input values --> '+this.selectedRowIds +'  --- '+this.formattedText);
            saveRecordOnClick({userStoryIds:this.selectedRowIds,formattedResponse:this.formattedText})
            .then(result=>{
                const evt = new ShowToastEvent({
                    title: 'Success',
                    message: 'Component Specification is Saved',
                    variant: 'success'
                });
                this.dispatchEvent(evt);
                this.dispatchEvent(new CustomEvent("savedrecord",{detail: this.isSaved}));
            })
            .catch(error=>{
                console.log('ERROR -->'+error.message);
            });
            this.isSaved=false;
        }
    }
  1. LWC componentB
import fetchData from '@salesforce/apex/apexControllerA.fetchData';
import { refreshApex } from '@salesforce/apex';
export default class ComponentB extends LightningElement {
    @wire gotConfirmation
    
    @wire(fetchData)
    wiredData({result}){
        this._wiredResults = result;
        if(result.data){
            let formattedData = [];
            data.forEach(record =>{
                formattedData.push({
                    id: Math.random(),
                    name:record.name,
                   });});
            this.data = formattedData;
            if(this.gotConfirmation){
                refreshApex(this.data);
            }
        }else if(result.error){
            console.log('error==>'+error);
        }
    }
}
  1. controller for fetching the data
public with sharing class apexControllerA {
   @AuraEnabled(cacheable=true)
    public static List<Map<String, Object>> fetchData(){
        List<objectA__c> userStoryList = [SELECT Id,name, Title__c FROM objectA__c Order By CreatedDate Desc];
        //logic
        List<Map<String, Object>> data = new  List<Map<String, Object>>();
       //some logic
        return data;
    }
}
1
  • Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer.
    – Community Bot
    Commented Mar 13 at 9:56

1 Answer 1

0

When dealing with multiple Lightning Web Components that interact with each other, such as in a tabbed interface where one component updates data and another displays it, ensuring that the display component reflects the latest data can be challenging. Here are some mechanisms to ensure that your data is refreshed across components:

  1. Event Communication: Use LWC's event system to communicate between components. After a successful save in componentA, dispatch a custom event that componentP listens for. When componentP receives this event, it can notify componentB to refresh its data.
  2. Imperative Apex: If refreshApex isn't working, you might need to call the Apex method imperatively in componentB after switching to TabB. This can be done in the connectedCallback or by using a handler for the custom event mentioned above.
  3. Cache Invalidation: Ensure that the Apex method used by componentB to fetch records is not using cacheable=true, as this could prevent the latest data from being retrieved. If it is, consider removing the cacheable property or using an imperative call to bypass the cache.
  4. Lightning Data Service: Utilize the Lightning Data Service features like getRecordNotifyChange() to notify components that depend on a record that the record's value has changed and they should refresh their data.

Here's a basic example of how you might implement event communication:

// componentA.js
this.dispatchEvent(new CustomEvent('recordchange'));

// componentP.js
handleRecordChange() {
// Notify componentB to refresh data
}

// componentB.js
@wire(getRecordsMethod)
records;

refreshData() {
return refreshApex(this.records);
}

In componentP, listen for the recordchange event and call a method in componentB to refresh the data, potentially using refreshApex.


Added Based On Comment:

Dispatch a Custom Event from componentA: After a successful save operation, dispatch a custom event to notify the parent component that the data has been updated.

// Inside componentA's saveComponentSpec method
this.dispatchEvent(new CustomEvent('recordchange'));

Handle the Custom Event in componentP: Listen for the recordchange event in componentP and handle it by calling a method in componentB to refresh the data.

// Inside componentP's JS
handleRecordChange() {
// Assuming componentB is active, refresh its data
if (this.tabLabel === 'TabB') {
const componentB = this.template.querySelector('c-component-b');
if (componentB) {
componentB.refreshData();
}
}
}

Refresh Data in componentB: Implement the refreshData method in componentB to refresh the wired data using refreshApex.

// Inside componentB's JS
@track _wiredResults;

refreshData() {
refreshApex(this._wiredResults);
}

Update the fetchData Apex Method: Make sure the fetchData method in your Apex controller is not cacheable if it's being used to fetch data that changes frequently.

@AuraEnabled(cacheable=false) // Set cacheable to false
public static List<Map<String, Object>> fetchData() {
// Your existing logic
}

Modify the HTML Template: Update the onsavedrecord event handler in componentP's HTML template to call the handleRecordChange method.

<!-- Inside componentP's HTML template -->
<c-component-a onsavedrecord={handleRecordChange}></c-component-a>

With these changes, when a record is saved in componentA, componentP will be notified, and if componentB is currently active, it will refresh its data to reflect the latest changes.

2
  • Have added the code snippet, could you please help me finding the issue? I tried, passing custom event from component A and the refreshing component B via parent componetP, but was not working as expected.
    – rmajumder
    Commented Mar 13 at 12:18
  • @rmajumder, I have updated the answer as per the comment please check. Commented Mar 13 at 13:23

You must log in to answer this question.

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