0

Controller class --

public class FinancialSearchController { 
     ...
     ...
     public Integration_Log__c mainOutboundLog {get;set;}

     //Constructor method definition here...

     //This is my action function
     public void logTransactionDetails () {

        String searchService = Apexpages.currentPage().getParameters().get('searchService');

        String searchTarget = Apexpages.currentPage().getParameters().get('searchTarget');

        mainOutboundLog = new Integration_Log__c();
        mainOutboundLog.User__c = System.userInfo.getUserId();

        mainOutboundLog.RecordTypeId = [Select SobjectType, Name, IsActive, Id, DeveloperName From RecordType Where SobjectType = 'Integration_Log__c' and IsActive = true and DeveloperName = :UTIL_ErrorConstants.OUTBOUND_LOG_RECTYPENAME Limit 1].Id;
        mainOutboundLog.Apex_Class_Name__c = 'FinancialSearchController';
        mainOutboundLog.Apex_Method_Name__c = '';
        mainOutboundLog.Service_Class_Name__c = '';
        mainOutboundLog.Web_Service_Method_Name__c = '';
        mainOutboundLog.Integration_Type__c = 'XYZ';
        mainOutboundLog.Context__c = searchService;
        mainOutboundLog.Remote_System__c = searchTarget;

        insert mainOutboundLog;
        //The above mainOutboundLog is getting inserted successfully.
}

//Another actionfunction which execute after the above actionFunction
Public void startSearch() {
  system.debug(mainOutboundLog); // This is printing Null.
}

Why is the controller variable (mainOutboundLog) which got successfully updated turns null in subsequent usage?

EDIT****VF snippet***

<script type="text/javascript">

        function checkValidations() {

        ... 
        ... 
            logTransactionDetails('Primary Search', 'XYZ'); 
            getSearchDetails();  
        } 
</script> 
<apex:actionFunction name="logTransactionDetails" action="  {!logTransactionDetails}" reRender="FinancialDataSearchForm"> 
     <apex:param name="searchService" value="" /> 
     <apex:param name="searchTarget" value="" /> 
</apex:actionFunction> 

<apex:actionFunction name="getSearchDetails" action="{!startSearch}" reRender="primaryResultsPanel, additionalResultsPanel, FinancialDataSearchForm">   
</apex:actionFunction> 

<apex:commandButton value="Search" onclick="checkValidations(); return false;" reRender="primaryResultsPanel, additionalResultsPanel"/> 
4
  • Are you calling logTransactionDetails before calling startSearch?
    – Adrian Larson
    Feb 22, 2017 at 4:56
  • 1
    Can you post your VF page code also?
    – Reshma
    Feb 22, 2017 at 5:03
  • @Adrian - Yes, logTransactionDetails is called before startSearch
    – Prasadium
    Feb 22, 2017 at 5:04
  • Added my VF code snippet as well\
    – Prasadium
    Feb 22, 2017 at 5:19

2 Answers 2

3

You should call second action function in onComplete of first action function. Then only it can ensure logTransactionDetails() is executed and value assigned to mainOutboundLog variable. Use this code snippet in vf page.

<script type="text/javascript">

        function checkValidations() {
            logTransactionDetails('Primary Search', 'XYZ'); 
            //No need to call here.
            //getSearchDetails();  
        } 
</script> 
<apex:actionFunction name="logTransactionDetails" action="{!logTransactionDetails}" onComplete="getSearchDetails();" reRender="FinancialDataSearchForm" > 
     <apex:param name="searchService" value="" /> 
     <apex:param name="searchTarget" value="" /> 
</apex:actionFunction> 

<apex:actionFunction name="getSearchDetails" action="{!startSearch}" reRender="primaryResultsPanel, additionalResultsPanel, FinancialDataSearchForm">   
</apex:actionFunction> 

<apex:commandButton value="Search" onclick="checkValidations(); return false;" reRender="primaryResultsPanel, additionalResultsPanel"/> 
0
2

ActionFunction is used to execute a method in your Apex Class from within your Visualforce Page asynchronously via AJAX requests. This VisualForce tag creates a JavaScript function in the rendered HTML page to call the action method. As this is an asynchronous call, in idle case you should wait for the response before firing any other event.

In your case, you are calling logTransactionDetails() and getSearchDetails() simultaneously. As both actions are called simultaneously and are asynchronous in nature, there is no guarantee that the updated variables (updated in logTransactionDetails()) are used in getSearchDetails.

What can you do here? Simply you should wait for the response from the first call, let's put 2 sec delay in calling the second method using setTimeout(); function as below.

logTransactionDetails('Primary Search', 'XYZ');
setTimeout(function(){ getSearchDetails(); }, 2000);

You can adjust the time to test the updated variables in the startSearch action. But in real life scenario, you don't know how long it will take to complete the execution of the first action. To save us from this, Salesforce provides a callback functionality in <apex:actionFunction tag in form of onComplete attribute. It takes one JavaScript function name and the function is called when the action sends the response. So you can use this attribute to call your second ActionFunction i.e. getSearchDetails(). Reshma has already described how to modify your code. Refer to her answer for the code example.

0

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.