We have a Lightning Component showing a span tag with class slds-badge
. We add another class to the tag depending on a field value of a Account. We show this component on the record page of said Account, so within the standard app, not a custom one.
Our component correctly renders the different colours based on the class returned from the controller when we open the Account page. Our challenge lies in the fact that we want to update the component when the field value changes. However, we are having trouble catching the event that fires (if there is an event in the first place) when the field change is saved.
We tried catching the aura:waiting or aura:doneWaiting events, which didn't really work as these events fire a lot (hundreds of times) during the page life cycle. The thing we tried next was to listen to the event fired when a toast is shown, which typically happens when a field change is succesful or a related object (like a task) is created. All in all this works, but we're not totally satisfied with the situation, because what happens if Salesforce decides to stop showing toasts after a record is saved?
Do you know of any more robust ways to listen to events on field change?
Component code
<aura:component implements="flexipage:availableForAllPageTypes,force:hasRecordId" access="global" controller="stagebar_Account_Lightning">
<aura:attribute name="iscont" type="Boolean" default="true"/>
<aura:attribute name="recordId" type="Id"/>
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<aura:handler event="force:showToast" action="{!c.recordSaved}"/>
<div class="slds">
<ltng:require styles="/resource/SLDS103/assets/styles/salesforce-lightning-design-system-ltng.css"/>
<span aura:id="isContacted" class="slds-badge">{!$Label.c.Is_contacted}</span>
</div>
</aura:component>
JS Controller Code
({
doInit : function(component, event, helper) {
helper.getContacted(component);
},
recordSaved: function(component, event, helper) {
helper.getContacted(component);
}
})
The controller basically calls the init method again if it detects a toast.
Helper code
({
getContacted : function(cmp){
var action = cmp.get("c.accountIsContacted");
action.setCallback(this, function(a){
if(a.getState() === "SUCCESS"){
var cmpTarget = cmp.find("isContacted");
this.setBadgeColor(cmpTarget, a.getReturnValue());
}
});
$A.enqueueAction(action);
},
//Color the badges, helper method.
setBadgeColor: function(target, retValue) {
console.log("inside setBadgeColor");
if(retValue == 'green'){
$A.util.addClass(target, "slds-badge-green");
$A.util.removeClass(target, "slds-badge-yellow");
$A.util.removeClass(target, "slds-badge-grey");
$A.util.removeClass(target, "slds-badge-red");
}else if(retValue == 'yellow') {
$A.util.removeClass(target, "slds-badge-green");
$A.util.addClass(target, "slds-badge-yellow");
$A.util.removeClass(target, "slds-badge-grey");
$A.util.removeClass(target, "slds-badge-red");
} else if(retValue == 'grey'){
$A.util.removeClass(target, "slds-badge-green");
$A.util.removeClass(target, "slds-badge-yellow");
$A.util.addClass(target, "slds-badge-grey");
$A.util.removeClass(target, "slds-badge-red");
} else if(retValue == 'red'){
$A.util.removeClass(target, "slds-badge-green");
$A.util.removeClass(target, "slds-badge-yellow");
$A.util.removeClass(target, "slds-badge-grey");
$A.util.addClass(target, "slds-badge-red");
}
}
])
Apex Controller (only relevant code)
@AuraEnabled
public static String accountIsContacted() {
if(currentAccount.LastActivityDate > Date.today().addYears(-1) && currentAccount.LastActivityDate != null){
return badgeColor.green.name();
} else {
return badgeColor.yellow.name();
}
}
Best Answer
I recommend you look at this page in the Lightning Components Documentation: Calling a Server-Side Action.
Using parts of the example code provided, you could set up a server-side "echo" that gets returned to your client side controller when the action method is complete as described at the bottom of the 2nd code section on that page following where the action method is enqueued:
There are several notes on the page of importance. This note may one that applies to what's happening in your code:
One of things to note that could also be useful to you is the following:
Additionally, there's this:
Should none of the above solve your issue, It would seem your only recourse will be to insert the record yourself in a synchronous operation if you want to improve performance and obtain reliable confirmation within your component that the action method has completed.