0
{"rates":{"2019-01-03":{"CAD":1.7043139339,"EUR":1.1072725662,"USD":1.2565329081},"2019-01-04":{"CAD":1.7033382229,"EUR":1.111259279,"USD":1.2671689559},"2019-01-02":{"CAD":1.7242832585,"EUR":1.1090778018,"USD":1.2640159707}},"start_at":"2019-01-01","base":"GBP","end_at":"2019-01-05"}

when I try to convert to a list I get an error

 public class updateExchangeRates {

        public class cls_rate {
            public rates rates;
            public String base;
            public Date date_x;
        }    
        public class rates {
            public Decimal CAD;
            public Decimal EUR;
            public Decimal USD;
        }

        public class exchangeRateList {
            public List<Exchange_Rate__c> cls_rate;
        }

        public void getExchangeRatesList(){
            Http http = new Http();
            HttpRequest request = new HttpRequest();
            request.setEndpoint('https://api.exchangeratesapi.io/history?start_at=2018-01-01&end_at=2018-02-01&symbols=USD,EUR,CAD&base=GBP');
            request.setMethod('GET');
            HttpResponse response = http.send(request);
            // If the request is successful, parse the JSON response.
            //cls_rate rat = new cls_rate();
            if (response.getStatusCode() == 200) {

                List<Exchange_Rate__c> exchangeList = (exchangeRateList) System.JSON.deserialize(response.getBody().replace('"date":', '"date_x":'), exchangeRateList.class);     


            }
        }
    }
  • 2
    That's because the JSON itself is not a list structure... it's a map structure ({} rather than []). If you want to make a list out of this, you will need to do some of your own conversion by deserializing it into a map structure first and then looping through the values of the map. – Chris Johnson Sep 17 at 19:22
  • Why not use this that will generate APEX bean for you?adminbooster.com/tool/json2apex – Pranay Jaiswal Sep 17 at 20:02
  • I would use this JSON2Apex website to generate a JSON parsing class. And then, I would use a Map to extract the necessary [Key, values] and then easy to extract the necessary values to be my list. Refer this post. – Arnold Jr. Sep 17 at 20:04
3

Worth putting JSON through e.g. https://jsonformatter.curiousconcept.com/ so the structure is clearer:

{ 
   "rates":{ 
      "2019-01-03":{ 
         "CAD":1.7043139339,
         "EUR":1.1072725662,
         "USD":1.2565329081
      },
      "2019-01-04":{ 
         "CAD":1.7033382229,
         "EUR":1.111259279,
         "USD":1.2671689559
      },
      "2019-01-02":{ 
         "CAD":1.7242832585,
         "EUR":1.1090778018,
         "USD":1.2640159707
      }
   },
   "start_at":"2019-01-01",
   "base":"GBP",
   "end_at":"2019-01-05"
}

Given the date strings used as property names (and no arrays are involved as Bryan says and https://json2apex.herokuapp.com/ doesn't AFAIK handle varying property names), probably easiest to walk through the maps in your code:

class Rate {
    String date;
    Decimal cad;
    Decimal eur;
    Decimal usd;
}

Rate[] rates = new Rate[] {};

Map<String, Object> rootMap = (Map<String, Object>) JSON.deserializeUntyped(jsonString);
Map<String, Object> ratesMap = (Map<String, Object>) rootMap.get('rates');
for (String date : ratesMap.keySet() {

    Map<String, Object> rateMap = (Map<String, Object>) ratesMap.get(date);

    Rate rate = new Rate();
    rate.date = date;
    rate.cad = (Decimal) rateMap.get('CAD');
    rate.eur = (Decimal) rateMap.get('EUR');
    rate.usd = (Decimal) rateMap.get('USD');

    rates.add(rate);
}
  • I learnt something new from this answer., i.e., JSONFormatter. You are the best, Keith! – Arnold Jr. Sep 18 at 14:31
2

The JSON being returned is not in a list

[{...},...]

Therefore you cannot cast it as a list

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.