5

I'm trying to make a webcall to pull data from an external webservice. After that call I would like to insert my data that comes in the form of JSON into my custom object called Company. However I am getting the following error: System.TypeException: Invalid conversion from runtime type LIST to MAP

Here is how the JSON would come in:

{"Id":"JOE1","Name":"Joes Software"}, {"Id":"REX1","Name":"Rex Software"} etc...

My class:

public with sharing class Callout {

public static void performAction(String method, String webCall){

            Blob headerValue = Blob.valueOf('username:password');  
            String endPoint = 'https://www.mockwebsite.com/WebAPI/api/';
            String jsonData;

            HttpRequest req = new HttpRequest();

            String authorizationHeader = 'Basic ' + EncodingUtil.base64Encode(headerValue);
            endPoint = endPoint + webCall;  
            req.setEndpoint(endPoint);
            req.setMethod(method);
            req.setHeader('Authorization', authorizationHeader);
            req.setHeader('Content-Type', 'application/json');

            Http http = new Http();
            HTTPResponse res = http.send(req);


            Map<String, Object> data = (Map<String, Object>)JSON.deserializeUntyped(res.getBody());  

            List<Object> items = (List<Object>)data.get('Items');
            List<Company__c> new_items = new List<Company__c>();
            for(Object item : items) {
            Map<String, Object> item_data = (Map<String, Object>)item;
            Company__c cpny = new Company__c();
            cpny.Name = (String)item_data.get('Name');
            cpny.Company_ID__c = (String)item_data.get('Id');
            new_items.add(cpny);
            }

  }
}

It doesn't like line

Map<String, Object> data = (Map<String, Object>)JSON.deserializeUntyped(res.getBody());

Any ideas? Thanks!

3
  • What is the line number where the error message indicates that there's a problem?
    – Mark Pond
    Oct 2, 2013 at 3:49
  • if you could give how the JSON response looks like we can help you debug and fix this simple issue Oct 2, 2013 at 4:55
  • The response looks like this: [{"Id":"OS","Name":"Orion Software"},{"Id":"CS","Name":"Constellation Software"}]
    – Jason J
    Oct 2, 2013 at 14:08

4 Answers 4

10

If the response type is known and this is going to be an ongoing process, would creating a response class for that make sense?

public class MockResponse{
  public String Id;
  public String Name;
}
...
List<MockResponse> responseList = (List<MockResponse>)JSON.deserialize(res.getBody(), MockResponse.class);
1
  • 4
    This wasn't working for me exactly. I used the following syntax: List<MockResponse> responseList = (List<MockResponse>)JSON.deserialize(res.getBody(), List<MockResponse>.class); Aug 14, 2015 at 14:09
7

According to the documentation, the method JSON.deserializeUntyped has a return type of Object, which means it can return different types of information depending on what's being fed into it.

I suspect in your case res.getBody() might be returning an array hence the inference of List, though you'll need to post the body content to know for sure. If it is a list then I guess you'll want to have a list of maps, but without more information it's hard to say. You definitely can't cast a list to map, but maybe you could get what you're after simply by indexing the first list element:

Map<String, Object> data = (Map<String, Object>)(JSON.deserializeUntyped(res.getBody())[0]);
4

Are you sure that is where it is bombing. It would appear to be bombing on the line below:

List<Object> items = (List<Object>)data.get('Items');

You're attempting to cast a map (data) to a list and I don't believe that is allowed.

-1

I actually had a similar issue and after analyzing it further, I realized that the JSON result returns a list of objects rather than a map which was causing the error. The same issue is occurring for you based on how you stated the JSON would return.

{"Id":"JOE1","Name":"Joes Software"}, {"Id":"REX1","Name":"Rex Software"}.... = List of JSON Objects - Your JSON List

{"animals":["majestic badger","fluffy bunny","scary bear","chicken"]} = JSON String associated within an object - Derived from Apex REST Callout Trailhead. When Mapping this to Map String, Object, "animal" would be stored in the String part and "["majestic badger","fluffy bunny","scary bear","chicken"]" as the Object thus, making it compatible with Map.

Please note that these are just my assumptions above. Hopefully, it will provide some insight. I am new to Apex so I am still learning.

I think working with JSON is more restrictive when it comes to converting lists to Maps because when working with regular sObject types (Account, Cases, etc...), one can convert. Here is a simple example code that I tried which worked:

List <Account> testAcc = [SELECT ID, Name FROM Account];

Map <Id, Account> testAccMap = new Map <Id, Account> (testAcc);

System.debug(testAccMap); 

Just making an observation.

You must log in to answer this question.

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