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

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!
  • 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 May 17 '17 at 19:50
  • Yes, for strings Decimal.valueOf will work only. @dana – Ashwani May 17 '17 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;

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.