function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Ken Koellner @ EngagewareKen Koellner @ Engageware 

Refresh lightning page data from VisualForce QuickAction

I know others have complained about this issue and I haven't found a solution anywhere.  I have a quick action that launches a VF page.  The page makes a minor change to the record and saves.  The pop-up with the VF page closes.  The data on the Lightning Page from which the QUick Action as launched does not have it's data refreshed. Further I found I had to reload the page three or four times before the change that was saved to the database finally appears on the page.  It seems it should be a trivial thing and very useful to make a change with VF.  Yes, lightning programming is wizz-bang cool but for quick and simple stuff when you don't have a lot of time or only have junior programmers available, VF is simpler and faster.


Below is an example.  It does update the record.  But when the action closes it takes several seconds and several reloads for the record in the Detail section of the Lightning page to reflect what has been in the database for several seconds.
public Account myAccount {get; private set;}
    ApexPages.StandardController  std;

    public KKAccountExperController() {
    }

    public KKAccountExperController(ApexPages.StandardController std) {
         Id accountId  = std.getId();
         myAccount = [ select Id, Industry from Account where Id =: accountId ];
         this.std = std;
    }


    public PageReference save() {
        update myAccount;
        PageReference ref = std.view();
        ref.setRedirect(true);
        return ref;
    }

    
}
 
<apex:page standardController="Account" extensions="KKAccountExperController" showQuickActionVfHeader="false">

    <apex:form>
        
        <apex:pageBlock>
            <apex:pageBlockButtons>
                <apex:commandButton value="Save" title="Save" action="{!save}"/>
            </apex:pageBlockButtons>

            <apex:inputField value="{!myAccount.Industry}"/>


        </apex:pageBlock>
                
    </apex:form>


</apex:page>



 
Alain CabonAlain Cabon
@Ken Kollner

The bad news is that there is no solution or workaround with a VFP.

 I asked Marcus Torres that question directly during a Ligthning Experience Tour in Paris and he just confirmed that this problem is inescapable.

VFP and Lex components are in separate "areas" and the direct refresh of the Lighthning page is impossible while the data are well saved after a VFP action. That can last ten seconds even if you use PF5 before you see the changes and Marcus Torres knows what he's talking about.

https://admin.salesforce.com/blog/2017/magic-lightning-components-marcus-torres

The good news is that a very simple lightning component (Aura) like below without Apex code works perfectly and the refresh is then immediate.

User-added imageimmediate.
 
<aura:component implements="force:lightningQuickAction,force:appHostable,flexipage:availableForRecordHome,force:hasRecordId"> 
    <aura:attribute name="showSpinner" type="Boolean" default="false" />   
    <aura:if isTrue="{!v.showSpinner}">
        <lightning:spinner />
    </aura:if>
    
    <lightning:notificationsLibrary aura:id="notifLib1" />       
    
    <lightning:card>    
        <lightning:recordEditForm 
                                  recordId="{!v.recordId}"
                                  objectApiName="Account"
                                  onload="{!c.handleLoad}"
                                  onsuccess="{!c.handleSuccess}"
                                  onerror="{!c.handleError}">
            <lightning:messages />
            
            <lightning:inputField fieldName="Industry"/>          
            
            <lightning:button class="slds-m-top_small" type="submit" variant="brand" label="Save" onclick="{!c.handleSave}" />
        </lightning:recordEditForm>
    </lightning:card>
    
</aura:component>
 
({
    handleSuccess: function (cmp, event, helper) {
        cmp.find('notifLib1').showToast({
            "title": "Record updated!",
            "message": "The record has been updated successfully.",
            "variant": "success"
        });
        cmp.set("v.showSpinner", false);
    },
    handleError: function (cmp, event, helper) {
        cmp.find('notifLib1').showToast({
            "title": "Something has gone wrong!",
            "message": event.getParam("message"),
            "variant": "error"
        });
    },    
    handleLoad : function(cmp, event, helper) {
        cmp.set("v.showSpinner", false);
    },   
    handleSave : function(cmp, event, helper) {
        cmp.set("v.showSpinner", true);
    },
})


There is not the close of the quickaction above so you can verify the immediate update of the main page while the quick action is still open.

 
Alain CabonAlain Cabon
"refreshment" and not "refresh".
Ken Koellner @ EngagewareKen Koellner @ Engageware
Thanks for the reply.  I kind of expected the behavior and was just curious if there was a workaround.  I do know that a Lightning component using the Lightning Data Service will cause anything on the page with the same record to immediately update and I will likely have to develop a lightning component.

I don't know if I will use recordEditForm directly or not.  I actually want to try not to.  I need to call the back end to do a bunch of work including some apex that does callouts.  But I will have to figure out a way to do the update of a couple fields in one record from the client via LDS to get the refresh.  It's the whole problem with the "two-tiered" archicture of a GUI attached directly to database record.  It's great for the simpler scenarios but then when your use case is gather a bunch of input and then do a variety of work, it starts to fall down and it's better if the GUI can call a service.

On why VF won't update the record, I suspect what is going on is Lightning has a client-side data store that has a cache of the record.  It's only like a "server on the client".  Until that cache times out (or something invalidates it), the old record is going to be shown.  That's why when the update is done via VF,  not only does it not refresh when the Quick Action exits but it doesn't refresh until several seconds and refreshes later.  What would be nice if if the Lightning JS library had a call you could make to invalidate a record in cache.  Thus it would force a refresh everywhere.
 
Alain CabonAlain Cabon
The problem is inescapable so most of the people "accept" (coerced, forced) this behavior given that nothing can be done excepted with very high prices (rewriting in Lightning components, easy to say but too much expensive for large existing projects).

Marcus Torres just talked about separate areas and it is probably the cache indeed (that was in 2017 but nothing new for this crucial problem).
It is above all a very bad news because the existing VFPs are great many.
The tool for the conversion of VFP in Lex components is imaginable (that exists perhaps).

<lightning:recordEditForm> works fine and you can target easily the fields ( <lightning:inputField fieldName="Industry"/>  ).

I mixed the <lightning:recordForm>  (display) <lightning:recordEditForm> (edit).

The migration with Ligthning components progressively remains interesting but there are new problems with these Lex components including for the mobile app (lookup not supported, so I am using a modified open source component).

I am very interesting myself to know if there is a new acceptable workaround for the VFP on Lex.

If you don't need a nice version for the mobile app (awfull date selector from the VFP on Android) and if this problem of refreshment was not so obvious, the VFPs would be still sufficient.
Ken Koellner @ EngagewareKen Koellner @ Engageware
I did get a full working example coded in a few hour.  I used force:recordData.  I started with the TrailHead project for using LDS.  A trivial Lightning App wraps that so it can be embedded in a VF page.  The VF has a few lines of script to load the page.  I then created one button and one quick action on Account.  Now, if classic, the button launches a new edit page and on save or cancel, returns to the record. The quick action lauches the component directly in a modal which closes on save or cancel with the record in the lightning detail page instantly reflecting the changes.

The trick to getting it to work nicely is there's a few lines of script in the Lightning controller.  It detects the theme and if Lightning, fires a close event.  If classic, it redirects the browser back to the record page (that might not work as expected in console.  In classic console, calling the record console JS method would likely be needed). 

I do like how LDS instantly updates all views of the record.  But I really don't love client-side logic.  My use case involves updating several records and also doing some callouts.  If an Apex methodcould be used, that could all be one transaction.  In my opinion service-oriented architecture is just better than two-tier record updates but that isn't how SF likes to work.  I think what I will do is create a small table with the info needed for all the work to be done.  Write a record to that table, then do an udpate to the standard object I'm working with, a trigger can detect that and if it sees a corresponding work record in the table, do all the work in the trigger.  I like calling services better than triggers but that's likely the most reliable way to do it.

If I get a chance, I'll zip up my example and post it to this thread.
Alain CabonAlain Cabon
As soon as you accept to write some Lex component or App, you can solve the problem. The minimal lex component above also works without a VFP inside it (simpler and direct) but you need a modified controller for the Apex server part if you have a lot of code (not difficult either with just some @AuraEnabled).

Directly from the VFP, there is no solution from the component or the controller.

Your solution with a Ligthning App that wraps a VFP page would be the only workaround where the VFP changes are immediate on the Lightning page.

I will test your workaround. It is very surprising that this workaround works while the standard navigation doesn't solve this problem yet when you switch directly in Lightning. Perhaps also a new option since 2017.
Alain CabonAlain Cabon
However, your solution is very interesting. Many people will be quite interested in it. 

I have big VFP myself with this problem and this workaround could be a nice solution before the rewriting in Lex.