6

After two days I'm out of ideas and hoping someone here could offer suggestions or even better -- tell me where I'm being silly!

I am trying to refresh the view of the child (recordForm) but it is not refreshing, it is displaying cached data, not SF database data. Even after destroying and re-creating it. Any ideas how to refresh it?

In cases where the external server directly changes SF data (via API) the Child needs to refresh its view and so it emits an event to the parent who then destroys and re-creates the child. BUT the child data shown is still the OLD data, not the new data that I can clearly see in SF database.

I display the GUID on the child and it seems to hardly change, I expected it would always be unique.

I have disabled cache in settings, re-logged in, tried different browsers. I can only think I'm not really destroying the child properly?

PARENT - COMPONENT

<!-- AccountManager.cmp -->
<aura:component controller='CRAccountGetService' implements='flexipage:availableForRecordHome,force:hasRecordId,force:hasSobjectName' access='global'>

<!-- Attributes-->
<aura:attribute name='recordId' type='string' default='{! v.recordId }' access='global' />
<aura:attribute name='sObjectName' type='string' access='global' />

<!-- Handlers -->
<aura:handler name='init' value='{! this }' action='{! c.handleInit }' />
<aura:handler name="refreshAccountForm" event="c:CRRefreshAccountForm" action='{! c.handleRefreshAccountForm }' />

   <!-- Screen -->
    <div>
       <!-- AccountForm dynamically injected here  -->
       {! v.body }
   </div>
</aura:component>

PARENT - CONTROLLER

 // AccountManagerController.js
  ({
    handleInit: function(component, event, helper) {
        helper.newAccountForm(component);
    },

   // handler for child component refresh event. Destroy & recreate account form component
    handleRefreshAccountForm: function(component, event, helper) {

    // destroy existing Account form child component
    var body = component.get("v.body");
    var arrayLength = body.length;
    for (var i = 0; i < arrayLength; i++) {
        body[i].destroy();
    }
    component.set('v.body',[]);

    // create new Account form child component
    var recId = component.get('v.recordId');
    $A.createComponent("c:AccountForm", { 'recordId': recId }, 
                        function (newAccountForm, status, errorMsg) {
                            if (status === "SUCCESS") {
                                component.set("v.body", newAccountForm);
                            } else {
                               // show error
                            }
                        });
    },
})

CHILD - COMPONENT

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

 <!-- Event to let parent (manager) know we need to be refreshed -->
    <aura:registerEvent name="refreshAccountForm" type="c:CRRefreshAccountForm" />
    <aura:attribute name='recordId' type='string' default='{! v.recordId }' access='global' />
    <aura:attribute name='mode' type='string' default='view' access='global' />

     <!-- Screen -->
     <lightning:messages />

    <lightning:recordForm 
        aura:id='accountForm' 
        objectApiName='Account'
        recordId='{! v.recordId }'
        layoutType='Full'
        columns='2'
        mode='{! v.mode }'
        onsuccess='{! c.handleSuccess }' 
    />
</aura:component>

CHILD CONTROLLER

 // AccountFormController.js
 ({
     // After a successful save to SF database, call external service
     handleSuccess: function(component, event, helper) {
         helper.callExternalService(component, event, helper).then (
            // promise resolved: external server accepted data. SF database unchanged
            $A.getCallback(function () {
                 helper.showToast('Account Save', 'All good', 'success', 1000);
             }),

             // promise rejected: external server rejected data and overwrote values in SF database, 
             // fire event so the Manager (the parent component) refreshes the form view
             $A.getCallback(function (message) { 
                 var refreshMeEvent = component.getEvent("refreshAccountForm");
                 refreshMeEvent.setParam("message", message);
                 refreshMeEvent.fire();
             })
         );
     },
 })

CHILD - HELPER

  // AccountFormHelper.js
  ({
      callExternalService: function(component,event, helper) {
         return new Promise($A.getCallback(function(resolve, reject) {

           var externalService = component.get('c.callExternalService');
               externalService.setParams({
                   'accountId': component.get('v.recordId')
              });

              externalService.setCallback(this, function(response) {
                  if (response.getState() === "SUCCESS") {
                       var rspMsg = JSON.parse(response.getReturnValue());
                       if (rspMsg.success) {
                           resolve();
                       } else {
                          reject(rspMsg.message);
                      }
                   } else {
                      reject('Controller failure:' + response.getState()); 
                  }
              });
               $A.enqueueAction(externalService);
          }));
      },
 })
  • now clarified! (I hope) – Etienne Jul 17 '18 at 13:51
  • :ok: 100% Thanks! btw, I believe there is a setting under session settings for caching, might want to check that – glls Jul 17 '18 at 13:54
  • hey glls - it's unchecked and I've tried flipping off lightning debug too – Etienne Jul 17 '18 at 14:07
3

I don't have documented proof of this, but I've also explored something similar to this and found these results, hopefully they point you in the right direction:

Per documentation, lightning:recordForm, lightning:recordEditForm, and lightning:recordViewForm all wrap force:recordData or some variant, which itself uses LDS.

However, it seems at the upper most layer, the lightning: namespace components do not expose the utility methods force:recordData have, such as:

component.find("forceRecordAuraId").reloadRecord({ skipCache: true });

My best guess on your current situation is that while your component is destroyed, LDS is actually not bound to the component, rather, the LEX container itself. So, the instance of LDS created by lightning: forms cannot be accessed by the component creating it.

As of Summer 18 (v43), I don't believe there is any way override the global LDS cache without going through one of the documented utility methods (i.e. force:recordData). If someone can show otherwise, I would also love to learn as I got stuck with something like this as well.

2

I STAND CORRECTED!

Apparently, we have an undocumented feature that will force the reload of data. Details are here: Forcing a refresh in force:recordData

But basically, just pass a parameter (doesn't matter what the name is) to the reloadRecord method of force:recordData like myLDS.reloadRecord(true). Just be aware that this will FORCE a server call (defeating the purpose of Lightning Data Service), but until we have cache invalidation implemented, it will work.

  • 1
    Is this applicable to lightning:recordForm too? I had tried at one point to call the same reloadRecord method but was unsuccessful. – tsalb Jul 18 '18 at 4:17
  • 2
    Yes -- just add a fields parameter to recordForm, and in the fields array just add a field that doesn't exist. – Greg Rewis Jul 20 '18 at 4:43
  • Just tried this now - with lightning:recordForm aura:id="recordForm", the command component.find("recordForm").reloadRecord(true); is showing the following error: component.find(...).reloadRecord is not a function – Brian Miller Jun 11 at 15:08
  • @BrianMiller you are trying to reload the form with reloadRecord. With recordForm, you don't need to call reloadRecord, but rather update the fields parameter with the name of a field that doesn't exist. Sorry for the confusion. – Greg Rewis Jun 12 at 18:03
1

Sadly, I've been asked about this several times over the last view weeks. This is a LDS issue that will be addressed by the upcoming cache invalidation feature that the LDS team is working on.

  • that should be "over the last few weeks". – Greg Rewis Jul 17 '18 at 19:34
  • Thanks all, glad it's not me (for a change ;) . Will work around for now and re-visit in a few weeks – Etienne Jul 17 '18 at 19:51
0

Waa this ever addressed? Experiencing the same in the aura lightningviewform making it useless for me. Was a fix only applied on the lwc version and not aura? If so I'll rewrite in that as I need the functionality of outfield but I needed it to refresh when I tell it to!! Frustrated to say the least

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.