4

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!

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

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);
| improve this answer | |
  • 2
    This wasn't working for me exactly. I used the following syntax: List<MockResponse> responseList = (List<MockResponse>)JSON.deserialize(res.getBody(), List<MockResponse>.class); – benedwards44 Aug 14 '15 at 14:09
6

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]);
| improve this answer | |
3

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.

| improve this answer | |
-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.

| improve this answer | |

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.