0

PLEASE NOTE: deserializeUntyped not deserialize!

I currently loop trough a jsonPayload which is working fine for the nodes of the first level.How can I achieve this for the node(s) of the second level without knowing the Keyset names as the first level. Please note that deserialize would not work since the Json is not known beforehand. I would like for the second level to end up with the corresponding nodes something like

string levelResource_1 = '{
  "Opp": [
    {
      "Oname": "Opp1",
      "CLdate": "02-02-2021",
      "Aname": "0019Y00001GAZDxZLX"
    },
    {
      "Oname": "Opp2",
      "CLdate": "03-03-2021",
      "Aname": "0019Y00001GAZDxZLX"
    }
  ]
}'

Currently working jsonPayload example:

    {
  "Accts": [
    {
      "jname": "Alice",
      "P": "+00 0600000000",
      "Showstopper": true,
      "Empl": "1-10"
    },
    {
      "jname": "Ben",
      "P": "+00 0611111111",
      "Showstopper": true,
      "Empl": "11-50"
    }
  ],
  "Cont": [
    {
      "lname": "Anton",
      "Ph": "+00 0600000000"
    },
    {
      "lname": "Bjorn",
      "Ph": "+00 0611111111"
    }
  ]
}

jsonPayload I want to traverse trough

    {
  "Accts": [
    {
      "jname": "Alice",
      "P": "+00 0600000000",
      "Showstopper": true,
      "Empl": "1-10",
      "Opp": [
        {
          "Oname": "Opp1",
          "CLdate": "02-02-2021",
          "Aname": "0019Y00001GAZDxZLX"
        },
        {
          "Oname": "Opp2",
          "CLdate": "03-03-2021",
          "Aname": "0019Y00001GAZDxZLX"
        }
      ]
    },
    {
      "jname": "Ben",
      "P": "+00 0611111111",
      "Showstopper": true,
      "Empl": "11-50"
    }
  ],
  "Cont": [
    {
      "lname": "Anton",
      "Ph": "+00 0600000000"
    },
    {
      "lname": "Bjorn",
      "Ph": "+00 0611111111"
    }
  ]
}

My Current apex

  Map<String, Object> levelResource_0 = (Map<String, Object>)JSON.deserializeUntyped(jsonPayLoad);   
    List<List<sObject>> sobjects = new  List<List<sObject>>();
    for(String keyLevel_0: levelResource_0.keySet()) { 
         system.debug('[UploadDocuments]levelResource_0.keySet(): ' + levelResource_0.keySet());         
        List<sObject> Newsobjects   = traverseJson(keyLevel_0, levelResource_0);
        sobjects.add(Newsobjects);
        for(String keyLevel_1: levelResource_0.keySet()) { 
        //How to get keylevels of second level _1 ?? levelResource_1.keySet()?!
        }
    }
2
6

The result from JSON.deserializeUntyped is either a List, Map, String, Boolean, or Decimal/Integer. You can detect these conditions dynamically, even recursively if you want to.

 Object source = JSON.deserializeUntyped(jsonString);
 if(source instanceOf Map<String, Object>) {
   Map<String, Object> values = (Map<String, Object>)source;
   for(String key: values.keys()) {
     Object subValue = values.get(key);
     if(subValue instanceOf List<Object>) {
       // This is a list of something //
     } else if(subValue instanceOf Map<String, Object>) {
       // This is another nested object //
     } else {
       // String, Boolean, or number
     }
   }
 }

Using instanceOf, you can detect if the property you're examining is a Map, and if so, you can cast it to a Map<String, Object> and parse those values. If you write a method for parsing these values, you can even do so recursively up to the stack limit.

Not the answer you're looking for? Browse other questions tagged or ask your own question.