[SalesForce] lightning:recordViewForm and force:recordData refresh issues

I'm having TestObject as parent object and New Custom Object having M-D relationship to it. TestObject having Min and Max Rollup summary fields which will rollup number field in child object.

I was rendering parent information using lightning:recordViewForm And force:recordData date service with certain fields, if we perform any dml in child need to refresh the parent record information.

Here's my Markup code:

<aura:component controller="MyCustomController" access="global">
    
    <aura:attribute name="records" type="List" access="public" default="[]" />
    <aura:attribute name="fields" type="List" access="public" default="Name,Max__c,Min__c" />
    
    <aura:attribute name="testObject" type="Map" access="public" default="{}" />
    <aura:attribute name="record" type="Map" access="public"/>
    
    <aura:attribute name="recordError" type="String" access="public"/>
    
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    
     <div>       
        <lightning:recordViewForm recordId="a0G2800000KJxZp" objectApiName="TestObject__c">
            <lightning:layout class=" slds-wrap custom-layout">
                <lightning:layoutItem size="4" padding="around-small">
                    <lightning:outputField fieldName="Name" class="output-element"/>
                </lightning:layoutItem>
                <lightning:layoutItem size="4" padding="around-small">
                    <lightning:outputField fieldName="Max__c" class="output-element"/>
                </lightning:layoutItem>
                <lightning:layoutItem size="4" padding="around-small">
                    <lightning:outputField fieldName="Min__c" class="output-element"/>
                </lightning:layoutItem>
            </lightning:layout>
        </lightning:recordViewForm>
            
        <div class="slds-box " style="padding:0px !important;">
            <lightning:button label="Save" variant="brand" onclick="{!c.update}" class="slds-m-right_medium" />
            <table class="slds-table slds-table_bordered slds-table_fixed-layout" > 
                <thead>
                    <tr class="slds-text-title_caps">
                        
                        <th scope="col">
                            <div class="slds-truncate" title="Name">Name</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Number">Number</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title=" Total"> Total</div>
                        </th>
                    </tr>
                </thead>   
                <tbody class="milestone-list"> 
                    <aura:iteration items="{!v.records}" var="record" indexVar="index">
                        <tr> 
                            <td>
                                <div class="slds-truncate" >
                                    <ui:inputText value="{!record.Name}" />
                                </div>
                            </td>
                            <td>
                                <div class="slds-truncate" >
                                    <ui:inputCurrency value="{!record.Number__c}" />
                                </div>
                            </td>
                            <td>
                                <div class="slds-truncate" >
                                    <ui:outputCurrency value="{!record.Number_Sum__c }" />
                                </div>
                            </td>
                        </tr>
                    </aura:iteration>
                </tbody>
            </table>
        </div>
        <force:recordData aura:id="recordData"
                              recordId="a0G2800000KJxZp"
                              fields="{!v.fields}"
                              targetRecord="{!v.record}"
                              targetFields="{!v.testObject}"
                              targetError="{!v.recordError}"
                              mode="EDIT" 
                              recordUpdated="{!c.recordUpdated}"/> 
    </div>
    
</aura:component>

I'm rendering the child records underneath the recordViewForm, when the child records updated i just want to refresh the parent record details.

Here's my controller code:

update : function(component, event, helper) {
        
    var action = component.get("c.updateParentValues");
    action.setParams({
        'updateList': component.get("v.records")
    });
    action.setCallback(this, function(response) {
        var state = response.getState();
        if (state === "SUCCESS") {
            component.set("v.records", response.getReturnValue());
            console.log('recordData-->', component.find("recordData"));
            component.find("recordData").reloadRecord();
            console.log('*** refresh is done');
        }
        
    });
    $A.enqueueAction(action);
    
},
recordUpdated : function(component, event, helper) {
    var changeType = event.getParams().changeType;
    console.log('**** change type-->', changeType);
    
    if (changeType === "CHANGED") { 
        component.find("recordData").reloadRecord();
    } 
}

Technically it should reload the record with this statement component.find("recordData").reloadRecord(), but it's not.

enter image description here
But in console if i store the value of the data service to the temp variable and ran this temp1.reloadRecord();, now the content is get refreshed.
enter image description here

Is there anything i'm missing here. Any ideas or suggestions are greatly appreciated.

Best Answer

The easy way to fire that refresh is to call the action that you passed in to the child record like so:

recordUpdated : function(component, event, helper) {
    var changeType = event.getParams().changeType;
    console.log('**** change type-->', changeType);

    if (changeType === "CHANGED") { 

        var action = component.get( "v.onUpdate" ); // get the Action passed in
        $A.enqueueAction( action ); // fire the action to refresh the parent

    } 
}

Since this action is an Aura.Action passed as a parameter it will queue right away instead of going through the controller action queue and you will see your parent record update since you called the action on the parent via the attribute on your child record. To implement, put your Params to the lightning:recordData in a component that houses the premade lightning component, receives the records, and the Aura.Action type attributes.

Your updated markup would look like:

<aura:component controller="MyCustomController" access="global">

    <aura:attribute name="records" type="List" access="public" default="[]" />
    <aura:attribute name="fields" type="List" access="public" default="Name,Max__c,Min__c" />

    <aura:attribute name="testObject" type="Map" access="public" default="{}" />
    <aura:attribute name="record" type="Map" access="public"/>

    <aura:attribute name="recordError" type="String" access="public"/>

    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />

     <div>       
        <lightning:recordViewForm recordId="a0G2800000KJxZp" objectApiName="TestObject__c">
            <lightning:layout class=" slds-wrap custom-layout">
                <lightning:layoutItem size="4" padding="around-small">
                    <lightning:outputField fieldName="Name" class="output-element"/>
                </lightning:layoutItem>
                <lightning:layoutItem size="4" padding="around-small">
                    <lightning:outputField fieldName="Max__c" class="output-element"/>
                </lightning:layoutItem>
                <lightning:layoutItem size="4" padding="around-small">
                    <lightning:outputField fieldName="Min__c" class="output-element"/>
                </lightning:layoutItem>
            </lightning:layout>
        </lightning:recordViewForm>

        <div class="slds-box " style="padding:0px !important;">
            <lightning:button label="Save" variant="brand" onclick="{!c.update}" class="slds-m-right_medium" />
            <table class="slds-table slds-table_bordered slds-table_fixed-layout" > 
                <thead>
                    <tr class="slds-text-title_caps">

                        <th scope="col">
                            <div class="slds-truncate" title="Name">Name</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Number">Number</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title=" Total"> Total</div>
                        </th>
                    </tr>
                </thead>   
                <tbody class="milestone-list"> 
                    <aura:iteration items="{!v.records}" var="record" indexVar="index">
                        <tr> 
                            <td>
                                <div class="slds-truncate" >
                                    <ui:inputText value="{!record.Name}" />
                                </div>
                            </td>
                            <td>
                                <div class="slds-truncate" >
                                    <ui:inputCurrency value="{!record.Number__c}" />
                                </div>
                            </td>
                            <td>
                                <div class="slds-truncate" >
                                    <ui:outputCurrency value="{!record.Number_Sum__c }" />
                                </div>
                            </td>
                        </tr>
                    </aura:iteration>
                </tbody>
            </table>
        </div>

        <c:recordViewComponent  recordId="a0G2800000KJxZp"
                                fields="{!v.fields}"
                                recordTarget="{!v.record}"
                                recordFields="{!v.testObject}"
                                error="{!v.recordError}"
                                mode="Edit"
                                onUpdate="{!c.update}" />

    </div>

</aura:component>

recordViewComponent:

<aura:component>
    <aura:attribute name="recordId" type="String" description="id of the record" />
    <aura:attribute name="fields" type="List" description="fields list" />
    <aura:attribute name="recordTarget" type="Map" description="" />
    <aura:attribute name="recordFields" type="List" description="" />
    <aura:attribute name="error" type="String" description="" />
    <aura:attribute name="onUpdate" type="Aura.Action" description="Aura Action on the parent record to fire on update" />
    <aura:attribute name="mode" type="String" description="record mode" />

    <force:recordData aura:id="recordData"
                          recordId="{!v.recordId}"
                          fields="{!v.fields}"
                          targetRecord="{!v.recordTarget}"
                          targetFields="{!v.recordFields}"
                          targetError="{!v.error}"
                          mode="{!v.mode}" 
                          recordUpdated="{!c.recordUpdated}"/> 
</aura:component>

recordViewComponent Controller:

recordUpdated : function(component, event, helper) {
    var changeType = event.getParams().changeType;
    console.log('**** change type-->', changeType);

    if (changeType === "CHANGED") { 

        var action = component.get( "v.onUpdate" ); // get the Action passed in
        $A.enqueueAction( action ); // fire the action to refresh the parent

    } 
}