function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ 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
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/
vfdbg fvdsgvfvfdbg fvdsgvf
This is something where I felt hopeless when I was working on my project and so I found an idea from this page (https://minimilitiamodapk.info/) about it.
Buster AllenBuster Allen
Hi there! It looks like you're trying to deserialize a JSON response from a REST API call into a custom object in your code.
The JSON response you provided contains information about a global value set and its picklist values. The JSON response has a hierarchical structure, with different levels of nesting. The top-level keys in the JSON object are "size", "totalSize", "done", "queryLocator", "entityTypeName", and "records".
To deserialize this JSON response, you need to create a custom object in your code that matches the structure of the JSON. In your case, it looks like you have created a wrapper class called "GlobalValueSetWrapper" with inner classes called "Metadata" and "CustomValue".
The error message you provided indicates that there might be an issue with the JSON syntax. Specifically, it seems like the JSON response might be missing a curly brace '{' at the beginning of an object. You may want to check the JSON response to make sure it's well-formed and doesn't contain any syntax errors. https://namecombinertool.com/
To get the "valueName" fields of the picklist values in the JSON response as a List<String>, you can access the "customValue" field in the "Metadata" object of your wrapper class. Then, you can iterate over the list of "CustomValue" objects and add the "valueName" field of each object to a new List<String>.
Here's some sample code to get you started:


// Deserialize the JSON response into your custom object
GlobalValueSetWrapper wrapper = (GlobalValueSetWrapper) JSON.deserialize(res.getBody(), GlobalValueSetWrapper.class);

// Get the list of picklist values from the metadata object in your wrapper
List<GlobalValueSetWrapper.CustomValue> customValues = wrapper.metadata.customValue;

// Create a new list to hold the valueNames
List<String> valueNames = new List<String>();

// Iterate over the list of custom values and add the valueName field to the new list
for (GlobalValueSetWrapper.CustomValue customValue : customValues) {
    valueNames.add(customValue.valueName);
}