Passing Parameters from Flow / Process builder to Apex

Firstly, I want to highlight the current limitations of Apex class if we want to call from the Admin favorite(Process builder / Visual flow) tools.

CLICK HERE to for limitations/Considerations. 

How to Pass Entire Object From Flow To Apex class :
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Requirement: From flow to apex class, how to pass all the contacts created today and which are associated with an Account.

Solution:
As per this requirement, the Parameter type must be List<List<Contact>> in Apex class. 
====================================================================
global class ClassCalledFromPB 
{
    @InvocableMethod(label='Method called From PB')
    global static void initialMethod(List<List<Contact>> request) 
    {        
        System.debug('--Printing values --- '+request);     
        // Busniness logic here
    }
}
====================================================================
Steps needs to follow in Flow:
Step 1 :
Create a Collection Variable to hold contact data.
Note: Reason for choosing collection variable is we are expecting multiple contact creations on any given day.

Step 2:
Create a fast lookup to fetch the data.
Note: The reason behind choosing fast look is, to fetch multiple values from Database, we need to use FastLookup. 

FastLookup in the backend 
List<Account> accList = [Select Name,Accountid from Contact];
Lookup in the backend
Account acc = [Select Name,AccountId from Contact Limit 1];

Conclusion: LookUp element can retrieve only 1 record from the Database whereas FastLookUp can retrieve multiple values from the DB.

Step 3:
In the above step, we have collected the data from the Contact object into a collection variable.  Now, it's time to call the Apex class from Flow.

How to Pass multiple values From Process builder  To Apex class :
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Limitations in Process builder :

1. Similar to flow(as shown in the above example), we can not pass entire Object directly from Process builder to Apex class.

2. The invocablemethod annotation will not accept multiple parameters it can take only 1 parameter. 
To avoid this limitation Salesforce provided a workaround.   

Workaround = Use [ InvocableVariable + Wrapper class ] combination

Note: Even if we want to pass multiple values to Apex class from Flow then we need to use the same workaround. 

Apex class:
====================================================================
global class ClassCalledFromPB 
{
    @InvocableMethod(label='Method called From PB')
    global static void initialMethod(List<WrapperClass> request) 
    {
        List<WrapperClass> cls = new List<WrapperClass>();
        for( WrapperClass wrp: request)
        {
            cls.add(wrp);
        }
        System.debug('--Printing values --- '+cls);     
    }
    
    global class WrapperClass 
    {
        @InvocableVariable
        global ID accountId;
        
        @InvocableVariable
        global String conName;
    }
}
====================================================================

Process builder :
One Last thing, similar to Triggers, in Process builder also, we can not perform callout in the same Transaction. So, the solution is to perform call-out in a different thread not inside invocableMethod.
Below is the pseudo code :
====================================================================
global class ClassCalledFromPB 
{
    @InvocableMethod(label='Method called From PB')
    global static void initialMethod(List<WrapperClass> request2)
    {
        List<WrapperClass> cls = new List<WrapperClass>();
        for( WrapperClass wrp: request2)
        {
            cls.add(wrp);
        }
        System.debug('--Printing values --- '+cls);   
        calloutToExternal();
    }    
    @future(callout=true)
    public static void calloutToExternal()
    {        
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals');
        request.setMethod('POST');
        request.setHeader('Content-Type', 'application/json;charset=UTF-8');
        // Set the body as a JSON object
        request.setBody('{"name":"mighty moose"}');
        HttpResponse response = http.send(request);
        // Parse the JSON response
        if (response.getStatusCode() != 201) {
            System.debug('The status code returned was not expected: ' +
                         response.getStatusCode() + ' ' + response.getStatus());
        } else {
            System.debug(response.getBody());
        }
    }
    global class WrapperClass 
    {
        @InvocableVariable
        global ID accountId;
        
        @InvocableVariable
        global String conName;
    }
}
====================================================================
What will happen if I try to implement the call-out logic inside invocableMethod ?
Answer: We will get a runtime error. 
System.CalloutException: You have uncommitted work pending.
Please commit or rollback before calling out

tHiNk gooD and dO thE bEsT.........MANJU NATH 🌝

Comments