[SalesForce] How to read JSON that contains field that can have different types

I am writing a callout in Apex with returns a JSON file with a field that does not have a consistent type. The JSON returned is quite complicated, so I have been trying to read the JSON with a Apex Class structure within salesforce, but this struggles with a varying field type. Is there any way to deal with this in Apex? The location of this varying field (in a fairly simple object list) makes me wonder if I could read only this list as a string so only have to use a nextToken etc for this section? simplified JSON and class structure below. value is the field that varies in type.

`

{
  "users": [
    {
      "id": 461774,
      "email": "test@test.co.uk",
      "name": "test Student",
      "sub_network_ids": [
        18307
      ],
      "custom_attributes": [
        {
          "id": 2310,
          "name": "isReady",
          "value": true,
          "type": "CustomizableAttribute::Boolean"
        },
        {
          "id": 2323,
          "name": "othernames",
          "value": "something",
          "type": "CustomizableAttribute::Text"
        }
      ]
    }
  ]

}`

Code:

public class HivebriteUserList{
    public List<HivebriteUserRecords> users;
}

public class HivebriteUserRecords{
    public String name;
    public String email;
    public List<HivebriteUserCustomAtt> custom_attributes;
    public List<Integer> sub_network_ids;

}

public class HivebriteUserCustomAtt{
    public String id;
    public String name;
    public String value;
}

Best Answer

For this situation, I would use JSON.deserializeUntyped that returns nested maps (for objects) and lists (for arrays). That allows the platform code to deal with all JSON related issues (such as escaping and syntax checking) without you having to write any code (such as the hard to get right nextToken stuff).

Your job is then to check what is in the maps -get using the names you expect - and lists and convert them to whatever data structure you want e.g. the classes you list. You are able to randomly walk about the model as you like rather than having to think about handling the nodes from first to last as you would with the JSONParser class.

If the variation is only by the type of a field, then you can store the value in an Object type property in your data structure:

public class HivebriteUserCustomAtt{
    public String id;
    public String name;
    public Object value;
}

and handle the various types elsewhere.

Or if you want to look at the types straight after parsing use e.g.:

Object value = m.get('value');
if (value instanceOf String) {
    String s = (String) value;
    ...
} else if (value instanceOf Boolean) {
    Boolean b = (Boolean) value;
    ...
} ...
Related Topic