+ Start a Discussion
RJ12RJ12 

Get values in a List from JSON

I'm doing a REST API call to get the global value set and trying to deserialize the JSON result to get the picklist values in a List<String>.

Here is the JSON:

{
  "size": 1,
  "totalSize": 1,
  "done": true,
  "queryLocator": null,
  "entityTypeName": "GlobalValueSet",
  "records": [
    {
      "attributes": {
        "type": "GlobalValueSet",
        "url": "/services/data/v53.0/tooling/sobjects/GlobalValueSet/0Nt59000000AAAAAAA"
      },
      "Metadata": {
        "customValue": [
          {
            "color": null,
            "default": false,
            "description": null,
            "isActive": null,
            "label": "USA",
            "urls": null,
            "valueName": "USA"
          },
          {
            "color": null,
            "default": false,
            "description": null,
            "isActive": null,
            "label": "Canada",
            "urls": null,
            "valueName": "Canada"
          }
        ],
        "description": null,
        "masterLabel": "US States & Territories",
        "sorted": false,
        "urls": null
      },
      "Id": "0Nt59000000AAAAAAA"
    }
  ]
}
I need help in fixing the error and also how to get valueNames in a List<String>

Error: System.JSONException: Malformed JSON: Expected '{' at the beginning of an object.

Here is what I have tried so far:

Wrapper:
    public class GlobalValueSetWrapper{
        Metadata metadata;

    public class Metadata {
        public List<CustomValue> customValue;
    }
    
    public class CustomValue {
        public String label;  
        public String valueName;
    }
    }


Class:
//calling API to get the JSON result
HttpResponse res = GlobalValueSetAPIHandler.getResponse('Countries');
GlobalValueSetWrapper wrapper = (GlobalValueSetWrapper) JSON.deserialize(res.getBody(), GlobalValueSetWrapper.class);
Best Answer chosen by RJ12
RJ12RJ12

I'm able to fix it.

public class GlobalValueSetWrapper{
    public List<Records> records;

    public class Records {
        public Metadata metadata;
    }
    
    public class Metadata {
        public List<CustomValue> customValue;
    }

    public class CustomValue {
        public String label;
        public String valueName;    
    }

    public static List<String> getPicklistValues(HttpResponse response){
        List<String> picklistValues = new List<String>();
        
        GlobalValueSetWrapper wrapper = (GlobalValueSetWrapper) System.JSON.deserialize(response.getBody(), GlobalValueSetWrapper.class);
        
        for(GlobalValueSetWrapper.customValue value : wrapper.records[0].metadata.customValue){
            picklistValues.add(value.valueName);
        }
        system.debug('Piclist Values: ' + picklistValues);
        
        return picklistValues;
    }
}

All Answers

Maharajan CMaharajan C
Hi RJ,

You have to use the below wrapper class for this. Just copy and paste the below code in your Org.

Better create a new wrapper class in your org and refer where you need. This wrapper class is generated by using JSON2APEX Salesforce.
 
public class GlobalPicklistJSON2Apex {
    public Integer size {get;set;} 
    public Integer totalSize {get;set;} 
    public Boolean done {get;set;} 
    public Object queryLocator {get;set;} 
    public String entityTypeName {get;set;} 
    public List<Records> records {get;set;} 
    
    public GlobalPicklistJSON2Apex(JSONParser parser) {
        while (parser.nextToken() != System.JSONToken.END_OBJECT) {
            if (parser.getCurrentToken() == System.JSONToken.FIELD_NAME) {
                String text = parser.getText();
                if (parser.nextToken() != System.JSONToken.VALUE_NULL) {
                    if (text == 'size') {
                        size = parser.getIntegerValue();
                    } else if (text == 'totalSize') {
                        totalSize = parser.getIntegerValue();
                    } else if (text == 'done') {
                        done = parser.getBooleanValue();
                    } else if (text == 'queryLocator') {
                        queryLocator = parser.readValueAs(Object.class);
                    } else if (text == 'entityTypeName') {
                        entityTypeName = parser.getText();
                    } else if (text == 'records') {
                        records = arrayOfRecords(parser);
                    } else {
                        System.debug(LoggingLevel.WARN, 'JSON2Apex consuming unrecognized property: '+text);
                        consumeObject(parser);
                    }
                }
            }
        }
    }
    
    public class Attributes {
        public String type {get;set;} 
        public String url {get;set;} 
        
        public Attributes(JSONParser parser) {
            while (parser.nextToken() != System.JSONToken.END_OBJECT) {
                if (parser.getCurrentToken() == System.JSONToken.FIELD_NAME) {
                    String text = parser.getText();
                    if (parser.nextToken() != System.JSONToken.VALUE_NULL) {
                        if (text == 'type') {
                            type = parser.getText();
                        } else if (text == 'url') {
                            url = parser.getText();
                        } else {
                            System.debug(LoggingLevel.WARN, 'Attributes consuming unrecognized property: '+text);
                            consumeObject(parser);
                        }
                    }
                }
            }
        }
    }
    
    public class Metadata {
        public List<CustomValue> customValue {get;set;} 
        public Object description {get;set;} 
        public String masterLabel {get;set;} 
        public Boolean sorted {get;set;} 
        public Object urls {get;set;} 
        
        public Metadata(JSONParser parser) {
            while (parser.nextToken() != System.JSONToken.END_OBJECT) {
                if (parser.getCurrentToken() == System.JSONToken.FIELD_NAME) {
                    String text = parser.getText();
                    if (parser.nextToken() != System.JSONToken.VALUE_NULL) {
                        if (text == 'customValue') {
                            customValue = arrayOfCustomValue(parser);
                        } else if (text == 'description') {
                            description = parser.readValueAs(Object.class);
                        } else if (text == 'masterLabel') {
                            masterLabel = parser.getText();
                        } else if (text == 'sorted') {
                            sorted = parser.getBooleanValue();
                        } else if (text == 'urls') {
                            urls = parser.readValueAs(Object.class);
                        } else {
                            System.debug(LoggingLevel.WARN, 'Metadata consuming unrecognized property: '+text);
                            consumeObject(parser);
                        }
                    }
                }
            }
        }
    }
    
    public class Records {
        public Attributes attributes {get;set;} 
        public Metadata Metadata {get;set;} 
        public String Id {get;set;} 
        
        public Records(JSONParser parser) {
            while (parser.nextToken() != System.JSONToken.END_OBJECT) {
                if (parser.getCurrentToken() == System.JSONToken.FIELD_NAME) {
                    String text = parser.getText();
                    if (parser.nextToken() != System.JSONToken.VALUE_NULL) {
                        if (text == 'attributes') {
                            attributes = new Attributes(parser);
                        } else if (text == 'Metadata') {
                            Metadata = new Metadata(parser);
                        } else if (text == 'Id') {
                            Id = parser.getText();
                        } else {
                            System.debug(LoggingLevel.WARN, 'Records consuming unrecognized property: '+text);
                            consumeObject(parser);
                        }
                    }
                }
            }
        }
    }
    
    public class CustomValue {
        public Object color {get;set;} 
        public Boolean default_Z {get;set;} // in json: default
        public Object description {get;set;} 
        public Object isActive {get;set;} 
        public String label {get;set;} 
        public Object urls {get;set;} 
        public String valueName {get;set;} 
        
        public CustomValue(JSONParser parser) {
            while (parser.nextToken() != System.JSONToken.END_OBJECT) {
                if (parser.getCurrentToken() == System.JSONToken.FIELD_NAME) {
                    String text = parser.getText();
                    if (parser.nextToken() != System.JSONToken.VALUE_NULL) {
                        if (text == 'color') {
                            color = parser.readValueAs(Object.class);
                        } else if (text == 'default') {
                            default_Z = parser.getBooleanValue();
                        } else if (text == 'description') {
                            description = parser.readValueAs(Object.class);
                        } else if (text == 'isActive') {
                            isActive = parser.readValueAs(Object.class);
                        } else if (text == 'label') {
                            label = parser.getText();
                        } else if (text == 'urls') {
                            urls = parser.readValueAs(Object.class);
                        } else if (text == 'valueName') {
                            valueName = parser.getText();
                        } else {
                            System.debug(LoggingLevel.WARN, 'CustomValue consuming unrecognized property: '+text);
                            consumeObject(parser);
                        }
                    }
                }
            }
        }
    }
    
    
    public static GlobalPicklistJSON2Apex parse(String json) {
        System.JSONParser parser = System.JSON.createParser(json);
        return new GlobalPicklistJSON2Apex(parser);
    }
    
    public static void consumeObject(System.JSONParser parser) {
        Integer depth = 0;
        do {
            System.JSONToken curr = parser.getCurrentToken();
            if (curr == System.JSONToken.START_OBJECT || 
                curr == System.JSONToken.START_ARRAY) {
                    depth++;
                } else if (curr == System.JSONToken.END_OBJECT ||
                           curr == System.JSONToken.END_ARRAY) {
                               depth--;
                           }
        } while (depth > 0 && parser.nextToken() != null);
    }
    
    
    
    
    private static List<CustomValue> arrayOfCustomValue(System.JSONParser p) {
        List<CustomValue> res = new List<CustomValue>();
        if (p.getCurrentToken() == null) p.nextToken();
        while (p.nextToken() != System.JSONToken.END_ARRAY) {
            res.add(new CustomValue(p));
        }
        return res;
    }
  
    private static List<Records> arrayOfRecords(System.JSONParser p) {
        List<Records> res = new List<Records>();
        if (p.getCurrentToken() == null) p.nextToken();
        while (p.nextToken() != System.JSONToken.END_ARRAY) {
            res.add(new Records(p));
        }
        return res;
    }
}


In Actual GlobalValueSetAPIHandler apex class please use the below code to get the picklist values:
 
String GLOBALVALUESETNAME = 'Country';  /// Global Picklist set name

HttpRequest req = new HttpRequest();
req.setHeader('Authorization', 'Bearer ' + System.userInfo.getSessionID());
req.setHeader('Content-Type', 'application/json');
req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm()+'/services/data/v50.0/tooling/query/?q=Select+Metadata,Id+FROM+GlobalValueSet+WHERE+DeveloperName=\''+GLOBALVALUESETNAME+'\'');
req.setMethod('GET');
Http request = new Http();
HttpResponse res  = request.send(req);

GlobalPicklistJSON2Apex wrappercls=  GlobalPicklistJSON2Apex.parse(res.getBody());

List<String> picklists = new List<String>();
for(GlobalPicklistJSON2Apex.customValue str : wrappercls.records[0].Metadata.customValue){
   system.debug( ' Piclist Value ==> ' +  str.label );
   picklists.add(str.label );
}

system.debug(' Picklist Values --> '  + picklists );


Thanks,
Maharajan.C
htyd hgrfjyhhtyd hgrfjyh
This is looking very important I wil add the same information in my new project here (https://basketballnieuws.com/) I was facing the values issue from one week.
RJ12RJ12

I'm able to fix it.

public class GlobalValueSetWrapper{
    public List<Records> records;

    public class Records {
        public Metadata metadata;
    }
    
    public class Metadata {
        public List<CustomValue> customValue;
    }

    public class CustomValue {
        public String label;
        public String valueName;    
    }

    public static List<String> getPicklistValues(HttpResponse response){
        List<String> picklistValues = new List<String>();
        
        GlobalValueSetWrapper wrapper = (GlobalValueSetWrapper) System.JSON.deserialize(response.getBody(), GlobalValueSetWrapper.class);
        
        for(GlobalValueSetWrapper.customValue value : wrapper.records[0].metadata.customValue){
            picklistValues.add(value.valueName);
        }
        system.debug('Piclist Values: ' + picklistValues);
        
        return picklistValues;
    }
}
This was selected as the best answer
aan thonyaan thony
Awesome work nice information uselful for me.The info you mentioned here will help me to complete my orginal quality (https://dissertationcapital.com/) project and wrapper class and I tried this code.
huihiu gyutuyhuihiu gyutuy
The equation is looking very useful and also you solved it in a very simple direction visit here (https://namemixers.com/last-name-combiner/) to learn some more interesting equations.
Ann HowardAnn Howard
Grand Summoners is a tactical role-playing game with battles occurring in real time. You will be using your army of frontline melees, ranged attackers, and support mages to battle across the Floating Islands to stop Varbu from unleashing his demon army onto his old world. Grand Summoners offers PvP gameplay in Arena Tournaments where you can get exclusive heroes that cannot be obtained anywhere else. In this guide we will go over the different tier list for each arena exclusive character - https://pingpong.fm/tier-list/grand-summoners/
Ann HowardAnn Howard
Grand Summoners is a tactical role-playing game with battles occurring in real time. You will be using your army of frontline melees, ranged attackers, and support mages to battle across the Floating Islands to stop Varbu from unleashing his demon army onto his old world. Grand Summoners offers PvP gameplay in Arena Tournaments where you can get exclusive heroes that cannot be obtained anywhere else. In this guide we will go over the different tier list for each arena exclusive character - https://pingpong.fm/tier-list/grand-summoners/
helsi ekorhelsi ekor
Can you share the complete scirpt of this program? I want to try this for my bitcoin stats page (https://smartmixers.io/).
helsi ekorhelsi ekor
You can find your market online. There are many online platforms like Google , Facebook to market your service and product online. If you have no idea how to use them, then try online services to promote your business on large scale with the help of digital marketing dc (https://www.vertigovisual.com/digital-marketing-agency-washington-dc/) marketing service company.