I have a parent component that uses lightning data service (lds) to get the record. This record is then shared to all of it's children as needed using data binding. I need to update the record using apex because some fields users are only allowed to update when using an api. After I make the callout, update the record, and then reload lds, the field values I retrieved from the api do not display in my UI. I need to manually refresh the page to see it, which is a bad user experience. Is it possible to reload lds after using apex to update the record? Here is what I did in my code.
Parent.cmp
<aura:attribute name="prescription" type="Case" />
<aura:attribute name="patient" type="Contact" />
<aura:attribute name="user" type="User" />
<aura:method name="reload" action="{!c.reload}" />
<force:recordData aura:id="prescriptionEditor"
recordId="{!v.recordId}"
targetFields="{!v.prescription}"
fields="Id,CoPayResult__c,AdditionalInsuranceMessage__c,Deductible_Remaining__c,Patient_Pay_Amount__c,Plan_Paid_Amount__c,RejectionCode__c,Verification_Errors__c"
mode="EDIT"
recordUpdated="{!c.handlePrescription}" />
<force:recordData aura:id="patientEditor"
recordId="{!v.prescription.Patient__c}"
targetFields="{!v.patient}"
fields="Id,Email"
mode="EDIT" recordUpdated="{!c.handlePatient}" />
<force:recordData aura:id="userEditor"
recordId="{!v.userId}"
targetFields="{!v.user}"
layoutType="FULL"
mode="EDIT"
recordUpdated="{!c.handleUser}" />
<c:Child prescription="{!v.prescription}"
parent="{! this }" />
ParentController.js
({
handlePrescription: function(component, event, helper) {
let prescription = component.get("v.prescription");
let eventParams = event.getParams();
//console.log(eventParams.changeType);
if(eventParams.changeType === "ERROR") {
helper.reload(component);
} else if(eventParams.changeType === "LOADED") {
//console.log("Prescription has loaded successfully.");
//console.log(JSON.parse(JSON.stringify(prescription)));
component.set("v.userId", $A.get("$SObjectType.CurrentUser.Id"));
let patient = component.get("v.patient");
let user = component.get("v.user");
if(patient == null && user == null) {
setTimeout($A.getCallback(function () { component.find("patientEditor").reloadRecord() }));
setTimeout($A.getCallback(function () { component.find("userEditor").reloadRecord() }));
}
} else if(eventParams.changeType === "CHANGED") {
helper.reload(component);
} else if(eventParams.changeType === "REMOVED") {
// record is deleted
//console.log("Record was removed.");
}
},
handlePatient: function (component, event, helper) {
let prescription = component.get("v.prescription");
let patient = component.get("v.patient");
var eventParams = event.getParams();
if (eventParams.changeType === "LOADED") {
// record is loaded (render other component which needs record data value)
//console.log("Patient has loaded successfully.");
//console.log(JSON.parse(JSON.stringify(component.get("v.patient"))));
}
else if (eventParams.changeType === "CHANGED") {
// record is changed
//console.log("Record was changed.");
} else if (eventParams.changeType === "REMOVED") {
// record is deleted
//console.log("Record was removed.");
} else if (eventParams.changeType === "ERROR") {
// there’s an error while loading, saving, or deleting the record
//console.log("error.");
}
},
handleUser: function (component, event, helper) {
let user = component.get("v.user");
let eventParams = event.getParams();
if (eventParams.changeType === "LOADED") {
//console.log("User has loaded successfully.");
//console.log(JSON.parse(JSON.stringify(user)));
}
else if (eventParams.changeType === "CHANGED") {
// record is changed
//console.log("Record was changed.");
} else if (eventParams.changeType === "REMOVED") {
// record is deleted
//console.log("Record was removed.");
} else if (eventParams.changeType === "ERROR") {
// there’s an error while loading, saving, or deleting the record
}
},
reload: function (component, event, helper) {
helper.reload(component);
}
})
ParentHelper.js
reload : function(component) {
setTimeout($A.getCallback(function () {
console.log('reloaded');
component.find("prescriptionEditor").reloadRecord();
component.find("patientEditor").reloadRecord();
}));
}
Child.cmp
<aura:component>
<aura:attribute name="parent" type="Aura.Component"/>
<aura:attribute name="prescription" type="Case" />
<div class="slds-grid slds-wrap">
<aura:if isTrue="{!!v.editing}">
<!-- Save/Cancel buttons -->
<div class="slds-grid slds-medium-size--3-of-3 slds-grid_align-end">
<div class="slds-p-left_xx-small">
<c:GrandChild prescription="{#v.prescription}"
parent="{!v.parent}"/>
</div>
<div class="slds-p-left_xx-small">
<lightning:button variant="brand"
label="Edit"
onclick="{!c.toggleEditing}"/>
</div>
</div>
<!-- Edit button -->
<aura:set attribute="else">
<div style="text-align:right;" class="slds-medium-size--3-of-3">
<lightning:button variant="brand" label="Save" onclick="{!c.save}" />
<lightning:button variant="brand" label="Cancel" onclick="{!c.toggleEditing}" />
</div>
</aura:set>
</aura:if>
</div>
</aura:component>
GrandChild.cmp
<aura:component implements="force:lightningQuickAction" controller="GrandChildController" >
<aura:attribute name="parent" type="Aura.Component"/>
<aura:attribute name="prescription" type="Object"/>
<button class="slds-button slds-button--brand" onclick="{!c.callHealthConnexxAndClose}">Verify</button>
</aura:component>
GrandChildController.js
({
callHealthConnexxAndClose : function(component, event, helper)
{
var action = component.get("c.getInsuranceVerification");
action.setParams({caseId: component.get("v.prescription.Id") });
action.setCallback(this, function(response)
{
var state = response.getState();
if (state === "SUCCESS") {
} else if (state === "INCOMPLETE") {
} else if (state === "ERROR") {
console.log("Failed with state: " + state);
console.log(response.error[0].message);
}
let p = component.get("v.parent");
p.reload();
});
$A.enqueueAction(action);
},
})
GrandChildController.apxc
public class GrandChildController {
@AuraEnabled
public static void getInsuranceVerification(Id caseId) {
//System.debug('Received ' + caseIds.size() + ' Cases');
List<Case> casesToUpdate = new List<Case>();
Case c = [SELECT Id FROM Case WHERE Id = :caseIds]
VerificationRequest req = new VerificationRequest(c);
VerificationResponse response = sendVerRequest(req);
if(response.calloutSuccess){
if(response.Reply.Message != null) {
String message = 'Response from TripleFIN: ' + response.Reply.Message;
AuraHandledException auraError = new AuraHandledException(message);
auraError.setMessage(message);
throw auraError;
}
Case p = new Case();
p.Id = c.Id;
p.CoPayResult__c = response.Reply.CoPay;
p.AdditionalInsuranceMessage__c = response.Reply.AdditionalInfo;
p.Deductible_Remaining__c = response.Reply.RemainingDeductableAmount;
p.Patient_Pay_Amount__c = response.Reply.PatientPay;
p.Plan_Paid_Amount__c = response.Reply.TotalAmountPaid;
String rejectCodeStr = '';
for(RejectCodes rc : response.Reply.RejectCodes){
rejectCodeStr += String.ValueOf(rc.RejectCode) + '; ';
}
p.RejectionCode__c = rejectCodeStr;
p.Verification_Errors__c = response.Reply.Errors != null ? String.valueOf(response.Reply.Errors) : null;
try {
update p;
} catch (DMLException e) {
String message = e.getMessage();
AuraHandledException auraError = new AuraHandledException(message);
auraError.setMessage(message);
throw auraError;
}
}
} }
I know this code is working, because when I refresh my UI, the values are there that are pulled in GrandChildController.apxc
. The problem appears to be when I'm calling reload()
from within GrandChild.cmp