Dynamic Picklist Value Retrieval

I have these two functions that are very similar. They retrieve picklist values for my aura components.

@AuraEnabled(cacheable=true)
public static List<Map<String,String>> getStatusPicklistValues() {
    List<Map<String,String>> statuses = new List<Map<String,String>>();

    for(Schema.PicklistEntry e : Case.Status.getDescribe().getPicklistValues()) {
        if(e.isActive()) {
            statuses.add(
                new Map<String, String> {
                    'label' => e.getLabel(),
                        'value' => e.getValue()
                        }
            );       
        }
    }

    return statuses;
}

@AuraEnabled(cacheable=true)
public static List<Map<String,String>> getCustomFieldPickListValues() {
    List<Map<String,String>> values = new List<Map<String,String>>();

    for(Schema.PicklistEntry e : Case.Custom_Field__c.getDescribe().getPicklistValues()) {
        if(e.isActive()) {
            values.add(
                new Map<String, String> {
                    'label' => e.getLabel(),
                        'value' => e.getValue()
                        }
            );       
        }
    }

    return values;
}

It would be nice if I could have one function like this

@AuraEnabled(cacheable=true)
public static List<Map<String,String>> getPickListValues(String fieldName) {
    List<Map<String,String>> values = new List<Map<String,String>>();

    for(Schema.PicklistEntry e : Case[fieldName].getDescribe().getPicklistValues()) {
        if(e.isActive()) {
            values.add(
                new Map<String, String> {
                    'label' => e.getLabel(),
                        'value' => e.getValue()
                        }
            );       
        }
    }

    return values;
}

Is that possible?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

You can use below method where you can pass objectName and comma separated picklist fields (even single field is fine) to get map of object and its picklist values of value and label:

@AuraEnabled 
public static Map<String, Map<String,String>> getPicklistValues(String objectName, String picklistFields) {

    if(string.isNotBlank(picklistFields)){            
        Map<String, Map<String,String>> picklistValuesMap = new Map<String, Map<String,String>>();

        for(String picklistField : picklistFields.split(',')){                
            picklistField = picklistField.trim();
            Schema.DescribeFieldResult stagesFR = Schema.getGlobalDescribe().get(objectName).getDescribe().fields.getMap().get(picklistField).getDescribe();
            List<Schema.PicklistEntry> stagesPle = stagesFR.getPicklistValues();

            Map<String,String> valuesList = new Map<String,String>();

            for( Schema.PicklistEntry s : stagesPle){
                valuesList.put(s.getValue(), s.getLabel());
            }                
            picklistValuesMap.put(picklistField, valuesList);                
        }            
        return picklistValuesMap;            
    }        
    return null;        
}

So, for getting picklist options for 2 fields – Type and Active__c from Account object:

System.debug(JSON.serialize(poc.getPicklistValues('Account', 'Type,Active__c')));

OUTPUT:

{
  "Active__c": {
    "Yes": "Yes",
    "No": "No"
  },
  "Type": {
    "Other": "Other translated",
    "Technology Partner": "Technology Translated",
    "Installation Partner": "Installation translated",
    "Channel Partner / Reseller": "Channel Partner Translated",
    "Customer - Channel": "Customer Channel Translated",
    "Customer - Direct": "Direct Translated",
    "Prospect": "Prospect Translated"
  }
}

Notice that we get label to value for each picklist field.

Also note that you can set comma separated fields as parameter or else just list of fields api strings by doing small change in code to just iterate over list of strings of fields. I just made it comma separated because whether you pass single or multiple fields, its fine (in case of list, you need to pass list of 1 field which could be confusing some times).

Method 2

Yep, it’s possible.

@AuraEnabled(cacheable=true)
public static List<Map<String,String>> getPickListValues(String fieldName) {
    List<Map<String,String>> values = new List<Map<String,String>>();

    for(Schema.PicklistEntry e : SObjectType.Case.fields.getMap().get(fieldName).getDescribe().getPicklistValues()) {
        if(e.isActive()) {
            values.add(
                new Map<String, String> {
                    'label' => e.getLabel(),
                    'value' => e.getValue()
                }
            );       
        }
    }

    return values;
}

Just to hightlight SObjectType.Case.fields.getMap().get(fieldName). Usually, you can use SObjectType prefix to do more dynamic staff. And there is also option to use

String sobjectName = 'Case';
String fieldName = 'Status';
List<PicklistEntry> picklistValues = Schema.getGlobalDescribe().get(sobjectName).getDescribe().fields.getMap().get(fieldName).getDescribe().getPicklistValues()

If you want to go one step further in the abstraction. Play around with this in Anonymous execute. Because sometimes it’s really hard to understand which code will compile and which not))

Good luck.

P.S. I would recommend to add checks for isAccessible() and check in general in fieldMap contains your fieldName.

Method 3

I appreciate all the answers. This is what works for my code. All the other answer appear to work as well.

@AuraEnabled(cacheable=true)
public static List<Map<String,String>> getPicklistValues(String objectName, String fieldName) {
    Boolean hasDefault = false;
    List<Map<String,String>> values = new List<Map<String,String>>();


    for(PicklistEntry e: ((SObject)(Type.forName('Schema.'+objectName).newInstance())).getSObjectType()
    .getDescribe().fields.getMap().get(fieldName).getDescribe().getPicklistValues()) 
    {
        if(e.isActive()) {
            values.add(
                new Map<String, String> {
                    'label' => e.getLabel(),
                        'value' => e.getValue()
                        }
            );       
        }  

        if(e.isDefaultValue()) {
            hasDefault = true;
        }
    }
    // we need to add a blank picklist value if a field has no default value,
    // because that means the field is blank in the UI.       
    if(!hasDefault) { 
        values.add(0,
                    new Map<String, String> {
                        'label' => '',
                            'value' => null
                            }
                   );         
    }

    return values;
}


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x