0

note : this is a follow up to this question

I'm following the approach on this post, and have created a class to use to deserialize a json string as I know the structure of the response.

I am able to deserialize the json to a map<string,decimal> but I receive an error if I try to deserialize to a list of an inner class that consists of a string and a decimal:

public class CurrentRate {
    string IsoCode;
    decimal value;
}

here is the structure of my JSON class, with the portion that doesnt work commented out:

public class myJSONClass{
    public string disclaimer;
    public string license;
    public string timestamp;
    public string base;
    // public currentRate[] rates;
    public map<string,decimal> rates = new map<string,decimal>();
}

The JSON being parsed is structured as follows

{
    "disclaimer": "Usage subject to terms: https://openexchangerates.org/terms",
    "license": "https://openexchangerates.org/license",
    "timestamp": 1506733203,
    "base": "USD",
    "rates": {
        "AED": 3.672611,
        "AFN": 68.671,
        "ALL": 113.870562,
        "AMD": 478.245,
        "ANG": 1.779798
   }
}

The deserialization is happening here:

string responseText = res.getBody();           
myJSONClass obj = (myJSONClass)JSON.deserialize(responseText, myJSONClass.class);   

And the error is:

System.JSONException: Expected List but found { at [line:5, column:16]

And here is the full code in case its helpful. I can work with the map, but it seems like I should be able to deserialize to a list and I want to know what I am doing wrong.

public class CurrencyUpdater {

    public class CurrentRate {
            string IsoCode;
            decimal value;
    }

    public class myJSONClass {
        public string disclaimer;
        public string license;
        public string timestamp;
        public string base;
        // does not work        public currentRate[] rates;
        public map<string,decimal> rates = new map<string,decimal>();
    }

    public list<CurrentRate> callEndpoint() {

          list<currentRate> OERRates = new list<currentRate>();   

          HttpRequest req = new HttpRequest();         
          req.setMethod('GET');
          req.setEndpoint('callout:OpenExchangeRates');                
          Http http = new Http();

          try {
              HTTPResponse res = http.send(req);                          
              string responseText = res.getBody();
              system.debug('responseText = ' + responseText);

              myJSONClass obj = (myJSONClass)JSON.deserialize(responseText, myJSONClass.class);   
              system.debug(obj.rates.keySet());                              

          } catch(System.CalloutException e) {

          }

         return OERRates;                       
    } 
}
1

To deserialize it as a list, you'd have to change your JSON:

"rates": [
    { "IsoCode": "AED", "value": 3.672611 },
    { "IsoCode": "AFN", "value": 68.671 },
    { "IsoCode": "ALL", "value": 113.870562 },
    { "IsoCode": "AMD", "value": 478.245 },
    { "IsoCode": "ANG", "value": 1.779798 }
  ]

At this point the currentRate[] would be the correct data type. If you can't change the JSON, then Map<String, Decimal> is your best alternative, assuming you don't want to enumerate all the possible currency codes that you may receive.

0

Your approach to create a Class based on the structure of the JSON string is spot on, but it was just a simple mistake on the "shape" of that Class. There's not an Array of rates in that JSON String.

Something that I use to help me with that is a JSON editor/linter rather than trying to figure it out in my head. I use JSON Editor Online (which I am in no way affiliated with), but there are more than a few available.

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.