5

This seems similar to other "Can not cast List to List" questions, except in the other cases the culprit tended to be custom sObjects, whereas nothing like that is relevant here.

Why is this cast illegal? What additional checks do I have to add?

I do this after I make an API call to a 3rd party service, and I get back some JSON, which is a string, and then I pass the string into this function, to transform it into what I want:

public List<Map<String, Object>> deserializeJson(String privcoDataString) {
boolean badApiCall = false;
List<Map<String, Object>> deserializedResults = new List<Map<String, Object>>(); 
    Object objResponse = JSON.deserializeUntyped(privcoDataString);

    if (objResponse instanceof Map<String, Object>) {
        Map<String, Object> mapResponse = (Map<String, Object>)objResponse;

    System.debug('mapResponse.get(data)'); 
    System.debug(mapResponse.get('data')); 

        List<Map<String, Object>> possibledeserializedResults = (List<Map<String, Object>>)mapResponse.get('data');

    if(possibledeserializedResults == null) {
    badApiCall = true; 
        } else if (possibledeserializedResults.isEmpty()) {
    badApiCall = true; 
        } else {
    deserializedResults = possibledeserializedResults;
    }

    } else {
    badApiCall = true; 
}

if (badApiCall) {
    System.debug(objResponse);
    ApexPages.Message msgErr = new ApexPages.Message(ApexPages.Severity.ERROR, 'Search Failed! Sorry!');
    ApexPages.addmessage(msgErr);
    Map<String, Object> errorMap = new Map<String, Object>();
    errorMap.put('bad_api_call', true); 
    deserializedResults.add(errorMap); 
}

    return deserializedResults;
}

This line gives me an error:

List<Map<String, Object>> possibledeserializedResults = (List<Map<String, Object>>)mapResponse.get('data');

The error is:

Invalid conversion from runtime type List to List>

And yet, as you can see, I have not declared data to be a List yet. It should be an Object and then in this line I narrow cast it. But it doesn't work.

Where would the code get the idea that "data" is List, and even if that is true, why can't I then narrow cast that to List<Map<String, Object>>?

In this case, data is a List full of Map instances. So the conversion should be valid.

  • 1
    you need to typecast it first to List<Object>, then iterate over each object and extract the map. I don't think it would allow you directly typecast to List<Map<String, Object>>. – Raul Oct 17 '16 at 15:18
10

I agree with Rahul's comment that the following is probably the best you can do:

String payload = '{"data": [{"s": "a", "i": 1}]}';
Map<String, Object> deserialized = (Map<String, Object>)JSON.deserializeUntyped(payload);
List<Map<String, Object>> data = new List<Map<String, Object>>();
for (Object instance : (List<Object>)deserialized.get('data'))
    data.add((Map<String, Object>)instance);    

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.