0

EDIT:

Object result = JSON.deserializeUntyped(payload);

if (result instanceof Map<String, Object>) {
    Map<String, Object> resultMap = (Map<String, Object>)result;
    system.debug('result: ' + resultMap.get('records')); //returns null
}

//END EDIT

How to loop through the nested json key/value for an example how can I get the values for this attributes Records==>attributes==>url or Metadata=>formula

APEX Code:

String payload = '.... json...'
Map<String, Object> jsonMap = (Map<String, Object>)JSON.deserializeUntyped(payload);     

List<Object> records = (List<Object>) jsonMap.get('records'); //get the records
if (records != null) {
    for (Object r : records) {
        //for (string r2 : r.get('url')) {  //error incorrect signature
             system.debug(r.value);
        //}
    }
} else {
    system.debug('null.. : ' + records);
}

JSON

{
  "size": 1,
  "totalSize": 1,
  "done": true,
  "queryLocator": null,
  "entityTypeName": "CustomField",
  "records": [
    {
      "attributes": {
        "type": "CustomField",
        "url": "/services/data/v46.0/tooling/sobjects/CustomField/00N6g00000TAlZNEA1"
      },
      "Metadata": {
        "businessOwnerGroup": null,
        "businessOwnerUser": null,
        "formula": "IMAGE( \nCASE(Rating__c, \n\"Very Bad\", \"/img/samples/stars_100.gif\",\n\"Bad\", \"/img/samples/stars_200.gif\",\n\"Okay\", \"/img/samples/stars_300.gif\", \n\"Good\", \"/img/samples/stars_400.gif\", \n\"Very Good\", \"/img/samples/stars_500.gif\", \n\"/img/samples/stars_000.gif\"), \n\"rating\")",
        "formulaTreatBlanksAs": "BlankAsZero"
      }
    }
  ]
}
  • Is it something you want to process in apex and return the resultant to lightning component? – salesforce-sas Jun 9 at 21:45
  • @salesforce-sas that's correct process in apex and return to lightning component – Nick Kahn Jun 9 at 22:10
  • @identigral my question does not answer the link you provided and before I post my question I gone through all the existing questions. – Nick Kahn Jun 9 at 22:11
  • @Nick Kahn The paragraph that begins with As a result, to access nested values in How do I get started working with JSON in Apex is very similar to your scenario. The payload isn't identical but it gives you enough to start with. – identigral Jun 9 at 22:19
  • Thanks @identigral, I updated my question I followed the link you provided and after reading this paragraph and modified my code, I still get the null values when I try to extract the key/value, please take a look. – Nick Kahn Jun 9 at 22:33
2

Below is how you deserialize in apex:

    String payload = '--payload--';
    Map<String, Object> jsonMap = (Map<String, Object>)JSON.deserializeUntyped(payload);     
    
    List<Object> records = (List<Object>) jsonMap.get('records'); //get the records
    if (records != null) {
        for (Object r : records) {
            Map<String,Object> rMap = (Map<String,Object>)r;
            Map<String,Object> attributes = (Map<String,Object>)rMap.get('attributes');
            Map<String,Object> Metadata = (Map<String,Object>)rMap.get('Metadata');
            System.debug(attributes);
        }
    } else {
        system.debug('null.. : ' + records);
    }

Note that there are invalid characters in formula in Metadata, so it will throw error, better to remove it and test. Later try to escape the new characters \n and check.


Better Solution

Whenever you are working in lightning components(aura or LWC), it is more efficient to return the string back to component to parse in javascript. Parsing in JS is much better and efficient than parsing in apex.

So, for the json you have given, below is how you can deserialize:

export default class App extends LightningElement {
    json = {
        "size": 1,
        "totalSize": 1,
        "done": true,
        "queryLocator": null,
        "entityTypeName": "CustomField",
        "records": [
            {
                "attributes": {
                    "type": "CustomField",
                    "url": "/services/data/v46.0/tooling/sobjects/CustomField/00N6g00000TAlZNEA1"
                },
                "Metadata": {
                    "businessOwnerGroup": null,
                    "businessOwnerUser": null,
                    "formula": "IMAGE( \nCASE(Rating__c, \n\"Very Bad\", \"/img/samples/stars_100.gif\",\n\"Bad\", \"/img/samples/stars_200.gif\",\n\"Okay\", \"/img/samples/stars_300.gif\", \n\"Good\", \"/img/samples/stars_400.gif\", \n\"Very Good\", \"/img/samples/stars_500.gif\", \n\"/img/samples/stars_000.gif\"), \n\"rating\")",
                    "formulaTreatBlanksAs": "BlankAsZero"
                }
            }
        ]
    };

    connectedCallback() {
        console.log(this.json.records);
        this.json.records.forEach(recItem=>{
            console.log(recItem.attributes.url);
            console.log(recItem.attributes.type);
        });
    }
}

Note that, you will be returning String from apex so you should parse it using JSON.parse.

Here is the working example

| improve this answer | |

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