+ Start a Discussion
Sushil_24Sushil_24 

How to use flow variables in apex class

The flow should call apex class to create new record. The field values are given in flow screen, the class should get the values to create record. I'm having trouble in passing the flow variable to class. How to use the flow input values in apex class. Can anyone help me out in this please.
Best Answer chosen by Sushil_24
Shweta AlwaniShweta Alwani
hi sushil,

use following class

public class InvokeApexFromFlowController{
    
    @InvocableMethod(label='Invoke Apex')
    public static List<FlowOutputs> invokeThisMetho(List<FlowInputs> request) {
        List<FlowOutputs> results = new List<FlowOutputs>();
        return results;
    }
    
    //input details that comes to apex from flow
    public class FlowInputs{
    
        @InvocableVariable
        public Account accountSobj;
        
        @InvocableVariable
        public String nameToBeUpdate;
        
    }
    
    //output details which goes from apex to flow
    public class FlowOutputs{
        
        @InvocableVariable
        public String accountPreviousName;
        
        @InvocableVariable
        public String DMLResult;
    }
}

Here we have created a wraaper class in flow input variable. In this wrapper class you can define more that one flow varriable and we are passing the intance of this wrapper class in invocable method.

User-added image

As I have defined two variable in "FlowsInput" wrapper class, so I am getting two option in picklist.

Please also refer this : http://acknowledgecloud.blogspot.com/2017/07/salesforce-invoke-apex-from-visual-flows.html

All Answers

mritzimritzi
Following is a sample class that will get values from Flow, you can use the values to create records as per your requirement.
This is a sample code, make changes wherever required.
 
public class MyAwesomeFlowHandlerClass {

   // Instance of the flow
   public Flow.Interview.My_Awesome_Flow_Name flowObj{get; set;}

   public void createRecord() {
      String lstName;
      //stop execution,if flow data is not available
      if (flowObj == null)
        return;
      //else create record using flow variables
      else{
        lstName = (String) myFlow.getVariableValue('flow_variable_name');
        //get other variables, the same way
        //You can create any record you want, Here I am showing contact creation
        Contact contact = new Contact(
            LastName = lstName,
            FirstName = 'Test'
            //add other fields, if required
        );
        insert contact;

   }
}

More info: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_forcecom_visualworkflow_vars.htm

Please mark this as Best Answer, if this helps solve your problem.
Shweta AlwaniShweta Alwani
Use invocable class.
https://help.salesforce.com/articleView?id=vpm_designer_elements_apex.htm&type=5
Sushil_24Sushil_24
@mritzi

Thanks mritzi, by doing this way my class is not showing in flow pallet section under apex. I can't able to call the class. Can you please tell me the alternate way
Sushil_24Sushil_24
@Shweta Alwani
In invocable class i can able to pass one value as parameter at a time, I need to pass other variables also, can you kindly brief your answer.
Shweta AlwaniShweta Alwani
hi sushil,

use following class

public class InvokeApexFromFlowController{
    
    @InvocableMethod(label='Invoke Apex')
    public static List<FlowOutputs> invokeThisMetho(List<FlowInputs> request) {
        List<FlowOutputs> results = new List<FlowOutputs>();
        return results;
    }
    
    //input details that comes to apex from flow
    public class FlowInputs{
    
        @InvocableVariable
        public Account accountSobj;
        
        @InvocableVariable
        public String nameToBeUpdate;
        
    }
    
    //output details which goes from apex to flow
    public class FlowOutputs{
        
        @InvocableVariable
        public String accountPreviousName;
        
        @InvocableVariable
        public String DMLResult;
    }
}

Here we have created a wraaper class in flow input variable. In this wrapper class you can define more that one flow varriable and we are passing the intance of this wrapper class in invocable method.

User-added image

As I have defined two variable in "FlowsInput" wrapper class, so I am getting two option in picklist.

Please also refer this : http://acknowledgecloud.blogspot.com/2017/07/salesforce-invoke-apex-from-visual-flows.html
This was selected as the best answer
Sushil_24Sushil_24
@Shweta Alwani Thanks Shweta, Its great..
Stuart FlemingStuart Fleming
Shweta Alwani,
Your answer provided me a way to declare variables and pass them to the apex class, but it does not tell you how to populate the public String accountPreviousName; and public String DMLResult; so that you can actually pass something back to the flow.
 
Thanks,
Stuart
Stuart FlemingStuart Fleming
Ok, I answered my own question on how to populate the parameters.  Also, I changed some names.  Test Class also included at bottom.

public class SSFInvokeMethod{
    // https://developer.salesforce.com/forums/?id=9060G0000005nusQAA

    @InvocableMethod(label='Invoke SSFInvokeMethod' Description='Update Account Object with new name')
    public static List<methodOutputs> invokeThisMethod(List<methodInputs> request) {
   
        // request[0].accountSobj is an Account Object record. 
        methodOutputs fo = new methodOutputs() ;
        fo.accountPreviousName =   request[0].accountSobj.Name ; 
        
          // Update the request[0].accountSobj (account object) Name to its new value
        request[0].accountSobj.Name = request[0].newAccountName ;
        try{
             update request[0].accountSobj ;
             fo.DMLResult = 'Success' ;
        } catch(Exception e){
             fo.DMLResult = 'Error' ;
        }

        List<MethodOutputs> theResults = new List<MethodOutputs>();
        theResults.add(fo) ;
        
        return theResults;
    }
           //input details that comes to apex from flow
    public class methodInputs{
        @InvocableVariable
        public Account accountSobj;
        
        @InvocableVariable
        public String newAccountName;
    }
    
    //output details which goes from apex to flow
    public class methodOutputs{
        @InvocableVariable
        public String accountPreviousName ;
        @InvocableVariable
        public String DMLResult ;
    } 
}


// Test Class

@isTest
public class SSFInvokeMethodTester {
    @isTest static void TestInvokeThisMethod(){   
    Test.startTest(); 
    String accountNameNew = 'How Now Brown Cow Enterprises' ;    
        
    //Create Account
    String AccountNameOrig ='Acme' ;    
    Account testAcct = new Account() ;
    testAcct.Name = AccountNameOrig ;
    testAcct.Phone = '(415)555-1212';
    testAcct.NumberOfEmployees = 100;
    Insert testAcct ;
 
    Account acctQuery = [select Id, Name from Account where Id = :testAcct.id  ]   ;
 
     // Load Input Parameters   
     SSFInvokeMethod.methodInputs params = new SSFInvokeMethod.methodInputs() ;
      params.accountSobj = acctQuery ;    
     params.newAccountName=accountNameNew; 
    
     List<SSFInvokeMethod.methodInputs> paramList = new List<SSFInvokeMethod.methodInputs>() ;
      paramList.add(params) ;
     List<SSFInvokeMethod.methodOutputs> returnedResults =  SSFInvokeMethod.invokeThisMethod(paramList) ;
        
     System.debug('result DMLResult:  ' +  returnedResults[0].DMLResult   ) ;
      System.debug('result accountPreviousName:  ' +  returnedResults[0].accountPreviousName   ) ;
        
     System.assertEquals( returnedResults[0].DMLResult , 'Success' , 'DMLResult failed assertion');   
     System.assertEquals( returnedResults[0].accountPreviousName , AccountNameOrig , 'accountPreviousName  failed assertion');       

       Test.stopTest();
    }
}