0

I am using LWC component in Case Record Page to show Warning Messages. There is no user interaction in this component. Case_Team__c is a Child Object to Case and when data is inserted/deleted/updated from related lists, i am creating platform event to notify my LWC component there is change in data, so i can invoke apex to get latest data and update Message in the HTML File.

Problem: After i receive response from the channel, I am invoking apex (this.loadMessages) to get latest results but result returned from GeoMsgRecords is from the initial apex call while loading the component. It doesn't trigger CaseGeoLocationController.getGeoMsgDetails to get the latest data.

CaseGeoLocationMsgCmp.js

import { LightningElement, wire,api, track } from 'lwc';
import GeoMsgRecords from '@salesforce/apex/CaseGeoLocationController.getGeoMsgDetails';
import { getRecord } from 'lightning/uiRecordApi';
import { subscribe, unsubscribe, onError, setDebugFlag, isEmpEnabled }  from 'lightning/empApi';

export default class CaseGeoLocationMsgCmp extends LightningElement {

    @track msgBanner;
    @api recordId;
 
    subscription = {};
    @api channelName = '/event/Case_Message__e';

    // Initializes the component
    connectedCallback() {
        // Register error listener     
        this.registerErrorListener();
        this.handleSubscribe();
        
    }


    registerErrorListener() {
        // Invoke onError empApi method
        onError(error => {
            console.log('Received error from server: ', JSON.stringify(error));
            //Error contains the server-side error
        });
    }

    handleSubscribe() {
        const messageCallback = (response) => {
            this.handleResponse(response);
        }


        // Invoke subscribe method of empApi. Pass reference to messageCallback
        subscribe(this.channelName, -1, messageCallback).then(response => {
            // Response contains the subscription information on subscribe call
            console.log('Subscription request sent to: ', JSON.stringify(response.channel));
            this.subscription = response;
        });
    }


    handleResponse(response){
        console.log('*** Inside outsideprocessing'+JSON.stringify(response));
        this.loadMessages();
    }

    
    loadMessages(){
        GeoMsgRecords({caseRecordId : this.recordId}).then(result => { 
//Here is the problem - I don't see apex call in the logs and returns old result invoked when component is initially loaded
            console.log('GEO MSG Banner in Load'+result);
            //if (result !== 'No Data') {
            if (JSON.parse(result).length>0) {
                this.msgBanner= JSON.parse(result);
            }
        }).catch(error => {
            console.log(error);
            
        });
    }


    
    @wire(getRecord, {recordId: '$recordId', fields: ['ContactId', 'AccountName']})
    retrigger({ error, data }) {
            if(data){
                console.log('refreshing Latest_____',data);
                this.loadMessages();
            }
    }

}

CaseGeoLocationMsgCmp.html

<template>
<div class="slds-text-heading_medium">
            <template if:true={msgBanner}>
                <div class="slds-box">
                    <div class="slds-text-color_error"><b>WARNING: </b></br></div>
                    <template for:each={msgBanner} for:item="banner">
                        <p key={banner.Location_Names__c}></br>{banner.Message_Line_One__c}</p>
                        <p key={banner.Location_Names__c}>{banner.Message_Line_Two__c}</p>
                    </template>
                    
    </div>
</template>

CaseGeoLocationController.cls

public with sharing class CaseGeoLocationController {


    public CaseGeoLocationController(){}
    
    @AuraEnabled(cacheable=true)
    public static string getGeoMsgDetails(string caseRecordId){

        List<Case_GEO_Location_Msg__mdt> geoMdtList = new List<Case_GEO_Location_Msg__mdt>();
        List<Case_Team__c> caseTeamList = new List<Case_Team__c>();
        Set<String> locationCountrySet = new Set<String>();


        caseTeamList = [SELECT ID, Contact__r.Location_Country__c, Role__c FROM Case_Team__c WHERE Case__c =: caseRecordId 
                            AND Contact__c != Null];
        if(caseTeamList.size()>0){
            for(Case_Team__c ct: caseTeamList){
                if(ct.Contact__r.Location_Country__c != null){
                    locationCountrySet.add(ip.Contact__r.Location_Country__c);
                } 
            }
            
            for(Case_GEO_Location_Msg__mdt cmdt: [SELECT MasterLabel, Location_Names__c, Message_Line_One__c, Message_Line_Two__c 
                                                  FROM Case_GEO_Location_Msg__mdt]){
                if(cmdt.Location_Names__c.indexof(',') > -1){
                    for(String st: cmdt.Location_Names__c.Split(',')){
                        if(locationCountrySet.contains(st)){
                            geoMdtList.add(cmdt);
                            break;
                        } 
                    }
                }else{
                    if(locationCountrySet.contains(cmdt.Location_Names__c)){
                        geoMdtList.add(cmdt);
                        
                    }
                }
            }
        } 
        
        return json.serialize(geoMdtList);
    }
}
4
  • I have tried refreshApex but it didn't work for me.
    – Venkat K
    Jul 9 at 2:02
  • Doesn't sound like you really want cacheable=true for that method then if you're looking to pull the latest each time you call it. Jul 9 at 17:24
  • I tried removing the cache but gives me this error message: "status":500,"body":{"message":"Apex methods that are to be cached must be marked as @AuraEnabled(cacheable=true)"
    – Venkat K
    Jul 9 at 19:27
  • Is this on a case record? And are you using any of the fields you're pulling in the @wire getRecord. I don't see the component using ContactId or AccountName? Jul 9 at 19:35
0

By having your apex call within the wire, you're forcing it to be cached when your use case doesn't seem to require that (trying to get latest data).

Not to mention, the getRecord call doesn't seem to be necessary as all you use is the recordId of the case and you already get that Id within recordId. The case Id can't change as it's living on the record itself.

With that in mind, you can add the call to your connectedCallback() instead of within the wire.

connectedCallback() {
    // Register error listener     
    this.registerErrorListener();
    this.handleSubscribe();
    //get messages here
    this.loadMessages();
}

This will allow you to then set your apex method to not cache

@AuraEnabled(cacheable=false)
    public static string getGeoMsgDetails(string caseRecordId){

And, when you handle the message, you'll be making a server trip each time to get the latest data

handleResponse(response){
    console.log('*** Inside outsideprocessing'+JSON.stringify(response));
    this.loadMessages();
}

If you still did need the getRecord wired method for any reason, simply separate the apex method call from it. Continue to call the apex method within connectedCallback() and let the wire method run separately

0

Thanks Kris. Makes Sense, I was using getRecord before implementing empApi. Now that i know when to refresh component via listening to Platform Event, it makes no sense to use getRecord in my scenario.

I am able to resolve using refreshApex. Earlier i made mistake via returning only {error, data} in wire function after changing it to full result i was able to get latest date from apex (LWC refresh apex not working https://www.salesforcepoint.com/2020/08/lwc-refresh-apex-Example.html)

@track responseFromGeoController;

@wire(GeoMsgRecords, ({caseRecordId : '$recordId'}))
    geoMessages(result) {
        this.responseFromGeoController = result;
}

Use refreshApex(this.responseFromGeoController); in handleResponse()

Let me also try using this.loadMessages() in connectedcallback to check i am not getting cached results in handleResponse().

Thanks for your time and explaining in detail about the cache.

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.