edited body
Source Link
Tyler Zika
  • 2.6k
  • 5
  • 26
  • 61

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 fields valuefield 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.

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 fields value 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.

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.

Source Link
Tyler Zika
  • 2.6k
  • 5
  • 26
  • 61

Reload Lightning Data Service after updating the record on the server

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 fields value 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:component implements="flexipage:availableForRecordHome,force:hasRecordId" controller="CallerAppController"> <ltng:require scripts="{!$Resource.lcUtility}" /> <ltng:require scripts="{!$Resource.AuthorizeDotNetUtility}"/>

<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 }" />
 

</aura:component>

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