1

I'm trying to handle a JSON response..the format it comes in is not the best but I can't change it..Ive used JSON2APEX and can access the object values individually but I need to loop through them

The JSON2APEX class goes like this

public class DataSource {


    public Data _PLU;
    public Data _1ST;
    public Data _VSL;
    public Data _ARC;
    public Data _ICN;
    public Data _REP;
    public Data _SNGLS;
    public Data _XAUR;
    public Data _DGD;

    public class Data {
        public String percentChange;
        public String baseVolume;
        public String quoteVolume;
    }


    public static DataSource parse(String json) {
        return (DataSource) System.JSON.deserialize(json,DataSource.class);
    }


}

so instead of this "DataSource._PLU.baseVolume" I want to do something like

for(DataSource o : Data){
    string s = o.baseVolume;
}

Any ideas? ps I've tried Map<string, Object> meta = (Map<string, Object>) JSON.deserializeUntyped(data); but when I try to loop through the keyset I can get the values but not drill down to each attribute

ex.

for(String obj : meta.keyset()){
    system.debug("sample"+meta.get(obj).baseVolume;
}

I get a variable doesn't exist error for baseVolume

1 Answer 1

3

When you use JSON.deserializeUntyped(data), you need to perform type casting to tell the Apex compiler what kind of object you're working with or you'll get errors because the type Object has no property baseVolume (e.g.).

One way to accomplish this would be:

for (Object obj : meta.keyset()){
    Data d = (Map<String, Object>)meta.get(obj);

    System.debug(d.get('baseVolume'))
}

This converts the untyped Object instance into a Map, whose get method you can use to obtain properties. (Unfortunately, you can't cast directly to a Data instance from a Map; please pardon my oversight).

If you do want to work with class instances rather than untyped Maps, you could also deserialize into a Map<String, Data>, which would have a keySet you could then iterate over.

5
  • Is there an issue, @JPG?
    – David Reed
    Commented Mar 5, 2018 at 12:23
  • Hi David, I've done what you suggested for (String key : meta.keyset()){ Data d = (Data)meta.get(key); System.debug(d.baseVolume); } but I'm receiving the following error System.TypeException: Invalid conversion from runtime type Map<String,ANY> to responseAPI.Data I've also tried to cast it into a custom object but get same error Thanks for the help!
    – JPG
    Commented Mar 5, 2018 at 12:24
  • Apologies for the oversight; I've updated above.
    – David Reed
    Commented Mar 5, 2018 at 13:12
  • Hi David, I was able to get it to work with the following code...now the question is could I streamline this or is this acceptable using best practices? Map<string,Object> meta = (Map<string,Object>) JSON.deserializeUntyped(rBody); for(String s : meta.keySet()){ Map<string,Object> markets = (Map<string,Object>) meta.get(s); String high = (String)markets.get('high'); String low = (String)markets.get('low'); \\logic here }
    – JPG
    Commented Mar 5, 2018 at 15:42
  • Hey @JPG, best to post a follow-up question with some specifics - comment threads get unwieldy fast. At a glance, it looks fine, but you'll want some error handling in case you get back weird JSON.
    – David Reed
    Commented Mar 5, 2018 at 15:49

You must log in to answer this question.

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