[SalesForce] JSON deserialization problem; Invalid conversion from runtime type LIST to LIST

I'm running code in Execute Anonymous

String responseLite = '[{"candidate_index" : 0, "delivery_line_1" : "address goes here", "input_index" : 0}]';


List<AddressVerification_Service.AddressVerificationResponse> responses = new List<AddressVerification_Service.AddressVerificationResponse>();
AddressVerification_Service.AddressVerificationResponse response1 = new AddressVerification_Service.AddressVerificationResponse();

//response1.input_index = '0';
response1.input_index = 0;
//response1.candidate_index = '0';
response1.candidate_index = 0;
response1.delivery_line_1 = 'address goes here';

responses.add(response1);

String responseJSON2 = JSON.serialize(responses);

System.debug(LoggingLevel.DEBUG,
  '\n\n --- FSM_AddressVerification_Service - verifyAddress - error --- '
  +'\n - response1 - json: ' + JSON.serializePretty(response1)
  +'\n - responses - json: ' + JSON.serialize(responses)
  +'\n'
);


try {
responses = new List<AddressVerification_Service.AddressVerificationResponse>();
            responses = (List<AddressVerification_Service.AddressVerificationResponse>)JSON.deserializeUntyped(responseJSON2);
response1 = new AddressVerification_Service.AddressVerificationResponse();
            //response1 = (AddressVerification_Service.AddressVerificationResponse)JSON.deserializeUntyped(responseLite);
        } catch(TypeException te) {
System.debug(LoggingLevel.DEBUG,
  '\n\n --- AddressVerification_Service - verifyAddress - error --- '
  +'\n - te: ' + te
  +'\n'
);
response1 = null;
        }
System.debug(LoggingLevel.DEBUG,
  '\n\n --- AddressVerification_Service - verifyAddress --- '
  +'\n - responses: ' + responses
  +'\n - response1: ' + response1
  +'\n'
);

So, debug output:

 --- AddressVerification_Service - verifyAddress - 1 --- 
 - response1 - json: {
  "input_index" : 0,
  "delivery_line_1" : "address goes here",
  "candidate_index" : 0
}
 - responses - json: [{"input_index":0,"delivery_line_1":"address goes here","candidate_index":0}]


 --- AddressVerification_Service - verifyAddress - error --- 
 - te: System.TypeException: Invalid conversion from runtime type LIST<ANY> to LIST<AddressVerification_Service.AddressVerificationResponse




 --- AddressVerification_Service - verifyAddress - 2 --- 
 - responses: ()
 - response1: null

Question: why the hell?

Best Answer

You're using JSON.deserializeUntyped, which always returns a MAP<String, Object> or a List<Object>, where each element may also be a map or list, recursively, until all elements are resolved. This is only useful when you don't know what data type you're expecting, or would be too complex to model in a class, or has reserved keywords in the attributes. In other words, most likely, you don't need to use this method at all. Instead, go about it this way:

String responseLite = '[{"candidate_index" : 0, "delivery_line_1" : "address goes here", "input_index" : 0}]';
try {
    List<AddressVerification_Service.AddressVerificationResponse> responses = (List<AddressVerification_Service.AddressVerificationResponse>)JSON.deserialize(responseLite, List<AddressVerification_Service.AddressVerificationResponse>.class);
} catch(Exception e) {
    // Handle your errors here
}

By the way, you don't need to initialize the object reference, because your second assignment is just another re-initialization. In other words, you're making more work for the script's garbage collector and wasting Apex Code CPU time.

Related Topic