How to create a Map collection in Flows? – Part 2(Flow map methods) #Spring20Delight

Hi, great to see you here! 😀

In my previous post of this series, we discussed about how we can create Map collection in flows. But there were also some limitations associated with it which are too hard to ignore. Today in this post, we gonna answer all those problems, thanks to the upcoming Spring 20 release.

After Spring 20 release, we will be able to pass sObject(and collection) as input and output parameters to Invocable methods(Hell, yes!). I have been waiting for this since a long time. 😈

Safe harbor, stuff that you are going to see in this post is not GA yet. But soon you will be able to use it once the Spring 20 is released to production environments. I am using a pre-release org for the demo purpose.

So today, you will be seeing a lot of Apex classes, don’t worry if you are an Admin, you can simply copy those classes in your Sandbox to test them out.

Why Invocable methods?

This is to make the life of our fellow admins easy so that they can use Map collection in flows without worrying about flow limits. And these methods will be directly available in Flows for you to call as Apex actions.

What are these Invocable methods about?

These methods are simply created to extend the usage of Map collection in Flows. Before we move forward with the discussion of methods, we will have to define a class which is going to act as our Map collection.

public class FlowMapClass {
    
    @AuraEnabled
    public string key; //Map key
        
    @AuraEnabled
    public sObject record; //sObject attribute for sObject Map type

    /* You can also choose to define a map key as something else
     * than an sObject type depending upon how you want your map to look like.
     */
}

Flow Map Methods

Following is the list of the Invocable methods that you will be able to use directly in your flows as Apex Actions.

1. Create Map in Flow

Use this method to directly create a sObject map.
Input(s):
-Collection of the records.
Output(s):
-Apex Defined collection variable of FlowMapClass type

Structure of the map will be: (id, record)

public class CreateFlowMapClass {
    
    @InvocableMethod(label='Create Standard Id-Record Map')
    public static CreateMapOutputs[] createMap(CreateMapInputs[] input){
        
        FlowMapClass[] flowMap = new FlowMapClass[]{};
        for(sObject sObj : input[0].records){
            FlowMapClass obj = new FlowMapClass();
            obj.key = (string)sObj.get('Id');
            obj.record = sObj;
            flowMap.add(obj);
        }
        CreateMapOutputs obj = new CreateMapOutputs();
        obj.flowMap = flowMap;
        
        CreateMapOutputs[] result = new CreateMapOutputs[]{};
            result.add(obj);
        return result;
    }
    
    /* Input(s) for Invocable method */
    public class CreateMapInputs{
        @InvocableVariable(label='List of records')
        public sObject[] records;
    }
    
    /* Output(s) for Invocable method */
    public class CreateMapOutputs{
        @InvocableVariable(label='Map')
        public FlowMapClass[] flowMap;
    }

}

2. Get all the keys from the Map

Use this method to get all the keys of a map collection.
Input(s):
– Apex defined collection variable(i.e. your map collection)
Output(s):
– Text collection variable

public class GetMapKeysClass {
    
    @InvocableMethod(label='Get all Map keys')
    public static GetKeysOutputs[] getkeys(GetKeysInputs[] input){
        string[] keySet = new string[]{};
        for(FlowMapClass obj : input[0].flowMap){
            keySet.add(obj.key);
        }
        GetKeysOutputs obj = new GetKeysOutputs();
        obj.keySet = keySet;
        GetKeysOutputs[] result = new GetKeysOutputs[]{};
            result.add(obj);
        return result;
    }
    /* Input(s) for Invocable method */
    public class GetKeysInputs{
        @InvocableVariable(label='Map' required=true)
        public FlowMapClass[] flowMap;
    }

    /* Output(s) for Invocable method */
    public class GetKeysOutputs{
        @InvocableVariable(label='Map Keyset' required=true)
        public string[] keySet;
    }

}

3. Get all values from the Map

Use this method to get all the values of a map collection.
Input(s):
– Apex defined collection variable(i.e. your map collection)
Output(s):
– Record collection variable

public class GetMapValuesClass {
    
    @InvocableMethod(label='Get all Map values')
    public static GetValuesOutputs[] getValues(GetValuesInputs[] input){
        sObject[] records = new sObject[]{};
        for(FlowMapClass obj : input[0].flowMap){
            records.add(obj.record);
        }
        GetValuesOutputs obj = new GetValuesOutputs();
        obj.records = records;
        GetValuesOutputs[] result = new GetValuesOutputs[]{};
            result.add(obj);
        return result;
    }

    /* Input(s) for Invocable method */
    public class GetValuesInputs{
        @InvocableVariable(label='Map' required=true)
        public FlowMapClass[] flowMap;
    }

    /* Output(s) for Invocable method */
    public class GetValuesOutputs{
        @InvocableVariable(label='Map Values' required=true)
        public sObject[] records;
    }

}

4. Get a value for a specific key from a Map collection

Use this method to get a ‘value’ mapped to a specific ‘key’ in the map collection.
Input(s):
– Apex defined collection variable(i.e. your map collection)
– Key
Output(s):
– Record variable

public class GetvalueFromMapClass{
    
    @InvocableMethod(label='Get Value from a Map key')
    public static GetValueOutputs[] getValue(getValueInputs[] input	){
        system.debug(input);
        GetValueOutputs[] result = new GetValueOutputs[]{};
        
        for(FlowMapClass loopObj : input[0].flowMap){
            if(loopObj.key == input[0].key){
                GetValueOutputs obj = new GetValueOutputs();
                obj.outputValue = loopObj.record;
                result.add(obj);
            }
        }
        
        return result;        
    }
    
    public class GetValueInputs{
        @InvocableVariable(label='Key' required=true)
        public string key;
        
        @InvocableVariable(label='Map' required=true)
        public FlowMapClass[] flowMap;
    }
    
    public class GetValueOutputs{
        @InvocableVariable(label='Value' required=true)
        public sObject outputValue;
    }
}

And there you go!
You now have 4 basic and useful Apex actions at your disposal to create and work with a Map collection!

Thank you for being an awesome reader! Subscribe to this blog for receiving all the latest updates straight to your inbox. 🙂

20 thoughts on “How to create a Map collection in Flows? – Part 2(Flow map methods) #Spring20Delight

  1. Pingback: How to create a Map collection in Flows by Narender Singh – UnofficialSF

  2. Pingback: How to create a Map collection in Flows? – Part 2(Flow map methods) #Spring20Delight —  forcePanda – SutoCom Solutions

  3. Pingback: From ForcePanda: The first Invocable Action that can perform SOQL on any kind of input – UnofficialSF

  4. Hi,

    Could you use this method (or variation of) to pull into a flow all of the fields that have been changed on a specific record?

    like map vs oldMap

    Like

  5. Hi,
    Thanks for your article. Its awesome.

    Could you please put the steps for Flow as well? How to add this in Flow, I’m trying to do it for Contact but facing issues.

    Like

  6. Hi,

    Thanks for the reply! I have to create a screen which will take input for Contact object like First Name, Last Name, Email, DOB etc. This screen has one checkbox field which says “do you want to add more contact?”, on checked, I have to load the same screen again till the checkbox is unchecked.

    No duplicate contact should be added if we click on Previous button.

    I have created a Apex class which has a Map. So, while adding a new contact I need to first check the whether contact is available in this Map, if no create it else don’t create.

    When I add the action, I’m not getting how to call the method which I have created to check whether the contact is available or not in the Map.

    Like

    • It should look something like this:
      {!recordCollectionvariable} CONTAINS {!recordVariable}

      If yes, do not add the recordVariable to collection, else, add.
      Then finally use the collection variable in ‘Create Records’ element.

      Like

  7. This is a great post. Thanks so much for sharing. I created the FlowMapClass with the string variable key and the sobject variable record. I think declared the apex defined variable in flow and was able to access the key variable in an assignment but the record variable. I think I am missing something and was wondering if you could provide some guidance.

    Like

  8. how to create map for Map opptyContactMap = new Map().key is opportunity ID,value is Contact ID. how to create map for different object .Please help

    Like

  9. Pingback: Apex Map Alternative within Salesforce Flow Builder. Ultimate Step-by-step Guide - Alex Furtuna

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.