10

I am trying to parse a complex JSON String using JSON.deserializeUntyped(). It parses the first level elements correctly but the second level elements come back as type ANY, even though I am expecting it to be another Map. Following is a sample JSON String.

{
    "totalResults": 2,
    "startIndex":0,
    "pricing":[
        {
            "price":10.80,
            "cost":9.22,
            "gp":12
        },
        {
            "price":5.50,
            "cost":4.00,
            "gp":24
        }
    ]
}

My Apex code is

Map<String, Object> resultsMap = (Map<String, Object>) JSON.deserializeUntyped(jsonStr);

List<Map<String, Object>> pricing = (List<Map<String, Object>>)resultsMap.get('pricing');

I get an error on the line 2.

Invalid conversion from runtime type LIST to LIST>

What am I doing wrong? Or what is correct way of getting the list of prices?

2 Answers 2

23

You can make the code work with an extra step:

String s = '{"totalResults": 2, "startIndex":0, "pricing":[{"price":10.80,"cost":9.22,"gp":12},{"price":5.50,"cost":4.00,"gp":24}]}';
Map<String, Object> m = (Map<String, Object>) JSON.deserializeUntyped(s);
List<Object> pricing = (List<Object>) m.get('pricing');
for (Object o : pricing) {
    Map<String, Object> p = (Map<String, Object>) o;
    System.debug('>>> ' + p);
}
2
  • 1
    Folks should be aware that Map<String, Object> p = (Map<String, Object>) o; can be used to create a key/value map on any object, which is quite handy :). Commented May 27, 2020 at 15:39
  • Hi @Shane, I'd phrase this as saying that the cast can be used to let the compiler know that something has the Map<String, Object> type when the compiler can't know that. The cast can't change some other type.
    – Keith C
    Commented May 27, 2020 at 16:43
7

In these situations I find it much more ... less frustrating to deserialize to a known type.

Given an exemplar JSON string, you can input it here: http://json2apex.herokuapp.com/ and this will generate classes and tests to deserialize the json. Very handy.

1
  • I don't want to create a concrete class for the JSON String. The reason being that the JSON response coming from external service is expected to change quite a few times in next few months. I am trying to keep things flexible in Apex so we don't have to make any changes in Apex classes whenever JSON changes. Designers can use the Map from deserialized JSON on the visualforce page.
    – Amit
    Commented May 9, 2014 at 13:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .