3

This returns the Object in the debug logs: 'USER_DEBUG [21]|DEBUG|{amount=1825.73, currency=USD}'

I really just want the price and could care less about the currency. How do I strip out just the price?

    Http http = new Http();
    HttpRequest request = new HttpRequest();
    request.setEndpoint('https://api.coinbase.com/v2/prices/spot?currency=USD');
    request.setMethod('GET');
    HttpResponse response = http.send(request);

    if (response.getStatusCode() == 200) {
        Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());

        List<Object> prices = new List<Object>();

        for(Object prc : results.values()) {
            prices.add(prc);
        }

        System.debug('Bitcoin Price:');

        for (Object prc : prices) {
            // This totally does not work, I want to strip the price value out
            Decimal price = prc.amount;
            // Above line is the question!

            System.debug(prc);
        }
    }

3 Answers 3

3

There are two common strategies:

  1. Use a wrapper class to deserialize into:

    class ResponseWrapper
    {
        final Decimal amount;
        final String currency;
    }
    

    And you would then deserialize slightly differently:

    List<ResponseWrapper> wrappers = (List<ResponseWrapper>)JSON.deserialize(
        response.getBody(), List<ResponseWrapper>.class
    );
    for (ResponseWrapper wrapper : wrappers)
    {
        system.debug(wrapper.amount);
    }
    
  2. Cast the Object to a Map<String, Object>

    for (Object price : prices)
    {
        Map<String, Object> data = (Map<String, Object>)price;
        system.debug(data.get('amount'));
    }
    
2

You don't need to dig into the object. Your response.getBody() must be like:

{"amount":1825.73, "currency":"USD"}

All you need to do is iterate over the map.

String jsonString = '{"amount":1825.73, "currency":"USD"}';
Map<String,Object> objMap = (Map<String,Object>)JSON.deserializeUntyped(jsonString);

    for(String key : objMap.keySet())
      System.debug(' Key: '+key + ' Value: '+objMap.get(key));

To get the amount only:-

Decimal amount = (Decimal)objMap.get('amount'); // typecasting!
2
  • 1
    When I queried coinbase.com I receive the amount as a string {"amount":"1821.86","currency":"USD"}. I think you may have to using Decimal.valueOf as opposed to casting here.
    – dana
    Commented May 17, 2017 at 19:50
  • Yes, for strings Decimal.valueOf will work only. @dana
    – Ashwani
    Commented May 17, 2017 at 20:01
1

The actual JSON looks something like this:

{  
   "data":{  
      "amount":"1821.86",
      "currency":"USD"
   },
   "warnings":[  
      {  
         "id":"missing_version",
         "message":"Please supply API version (YYYY-MM-DD) as CB-VERSION header",
         "url":"https://developers.coinbase.com/api#versioning"
      }
   ]
}

Using the "untyped" JSON API, you can access the amount as follows:

Map<String, Object> results = (Map<String, Object>)JSON.deserializeUntyped(response.getBody());
Map<String, Object> data = (Map<String, Object>)results.get('data');
Decimal amount = Decimal.valueOf((String)data.get('amount'));

If you want to de-serialize the result into a known type, declare the following classes:

public class SpotResult {
    public SpotResultData data { get; set; }
}

public class SpotResultData {
    public Decimal amount { get; set; }
    // 'currency' is a reserved word... luckily you don't need it :)
    //public String currency { get; set; }
}

Then, you can access the amount as follows:

SpotResult result = (SpotResult)JSON.deserialize(response.getBody(), SpotResult.class);
Decimal amount = result.data.amount;

You must log in to answer this question.

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