1

I need to parse this JSON, and then insert the values into a parent object, and then a list of child objects into the detail page of the parent. I'm having trouble with a few issues: I am unable to populate the the parent object fields because it starts outside of the START_ARRAY token. Also, having trouble with converting certain child fields to the correct data type (Percent and dollarAmount in my JSON from String to Decimal). Lastly, I was curious how I'm able to nest my JSON Parser so that each Parent object includes their child objects that I'm also parsing. I've included the JSON, and my class below. Thanks in advance!

I have already seen the JSON2Apex site. I've tried using JSON.DeserializeUntyped, my keys are dynamic, so I've read that isn't a viable solution.

Relevant Resource I've Used: Parse JSON into Lead

This is the most relevant resource that I've used, but it doesn't included nested JSON, which is where the complexities are that I'm having trouble with:

JSON to Parse

 {"ideal":[{"product":"4","percent":"25","dollarAmount":"11250"},{"product":"5","percent":"23","dollarAmount":"10350"},{"product":"3","percent":"20","dollarAmount":"9000"},{"product":"8","percent":"18","dollarAmount":"8100"},{"product":"7","percent":"15","dollarAmount":"6750"}],"idealFiltered":[{"product":"4","percent":"25","dollarAmount":"11250"},{"product":"5","percent":"23","dollarAmount":"10350"},{"product":"3","percent":"20","dollarAmount":"9000"},{"product":"8","percent":"18","dollarAmount":"8100"},{"product":"7","percent":"15","dollarAmount":"6750"}],"InBudget":[{"product":"4","percent":"70","dollarAmount":"7000"},{"product":"8","percent":"30","dollarAmount":"3000"}]}

Class

global class MicFire {
    id thisRecId;
    Recommendation_Request__c recParams;
    public String recResponseBody { get; set; }

    Recommendation_Response__c recResponse { get; set; }

    *Rest of my HTTP Request* 

     Http http = new Http();

     HTTPResponse res = http.send(req);

     recResponseBody = res.getBody();

     System.debug(recResponseBody);


     JSONParser parser = JSON.createParser(recResponseBody);

     Map<String, sObjectField> fieldMap = new Map<String, sObjectField>{
        'product' => Recommendation_Response_Product__c.Product__c,
        'percent' => Recommendation_Response_Product__c.Amount_Recommended__c,
        'dollarAmount' => Recommendation_Response_Product__c.Amount_Recomended__c,

        'ideal' => Recommendation_Response__c.Rec_Response_Type__c,
        'Ideal Filtered' => Recommendation_Response__c.Rec_Response_Type__c,
        'inBudget' => Recommendation_Response__c.Rec_Response_Type__c
     };


       // Recommendation Response
       Recommendation_Response__c recResponse;
       List<Recommendation_Response__c> recResponseList = new Recommendation_Response__c[0];

       // Recommendation Response Products
       Recommendation_Response_Product__c recResponseProd;
       List<Recommendation_Response_Product__c> recRespProdList = new Recommendation_Response_Product__c[0];
       String fieldName;

       while(parser.nextToken() != null) {

           if(parser.getCurrentToken() == JSONToken.FIELD_NAME){
               fieldName = parser.getText();
               continue;
           }

            if(parser.getCurrentToken() == JSONToken.FIELD_NAME && (fieldName == 'ideal' || fieldName == 'Ideal Filtered' || fieldName == 'inBudget')){
                recResponse.put(fieldMap.get(fieldName), parser.getText());
                fieldName = null;
                continue;
           }

           if(parser.getCurrentToken() == JSONToken.START_ARRAY){
               recResponse = new Recommendation_Response__c();
               continue;
           }

           if(parser.getCurrentToken() == JSONToken.START_OBJECT){
               recResponseProd = new Recommendation_Response_Product__c();
               continue;
           }

           if(parser.getCurrentToken() == JSONToken.FIELD_NAME && fieldName != null && fieldMap.containsKey(fieldName)){
                recResponseProd.put(fieldMap.get(fieldName), parser.getText());
                fieldName = null;
                continue;
           }

           if(parser.getCurrentToken() == JSONToken.END_OBJECT){
               recRespProdList.add(recResponseProd);
               recResponseProd = null;
               continue;
           }

           if(parser.getCurrentToken() == JSONToken.END_ARRAY){
               recResponseList.add(recResponse);
               recResponse = null;
               continue;
           }
       }
     /*  
       for(Recommendation_Response__c recType : recResponseList){
           try{
               insert recType;
           } catch(DMLException e){
               System.debug('Error with recType Insert: ' + e.getMessage());
           }
       }

       for(Recommendation_Response_Product__c recProd : recRespProdList){
           try{
               insert recProd;
           } catch(DMLException e){
               System.debug('Error with recProd Insert ' + e.getMessage());
           }
       }
       */
       //insert recRespProdList;
       System.debug('++++++++++++++++++++++++++++++++ Recommendation Response PRODUCT List: ' + recRespProdList);
       System.debug('++++++++++++++++++++++++++++++++ Recommendation Response List: ' + recResponseList);
   }
}

1 Answer 1

3

The method JSON.deserializeUntyped works well for this type of problem. What you get returned is a map:

Map<String, Object> m = (Map<String, Object>) JSON.deserializeUntyped(jsonString);

You can use the normal map methods to get hold of the keys or to see if a key is present. So for example to access the "ideal" list items:

List<Object> ideals = (List<Object>) m.get('ideal');
if (ideals != null) {
    for (Object ideal : ideals) {
        String product = (String) ideal('product');
        String percent = (String) ideal('percent');
        String dollarAmount = (String) ideal('dollarAmount');
        ...
    }
}

Because it is known that the data is a list (array) I've just cast the object to a list. If the content is of very unpredictable type you can also use instanceof tests in your logic.

Here is your JSON having been formatter by http://jsonformatter.curiousconcept.com/; this sort of formatting makes the JSON easier to understand:

{  
  "ideal":[  
    {  
      "product":"4",
      "percent":"25",
      "dollarAmount":"11250"
    },
    {  
      "product":"5",
      "percent":"23",
      "dollarAmount":"10350"
    },
    {  
      "product":"3",
      "percent":"20",
      "dollarAmount":"9000"
    },
    {  
      "product":"8",
      "percent":"18",
      "dollarAmount":"8100"
    },
    {  
      "product":"7",
      "percent":"15",
      "dollarAmount":"6750"
    }
  ],
  "idealFiltered":[  
    {  
      "product":"4",
      "percent":"25",
      "dollarAmount":"11250"
    },
    {  
      "product":"5",
      "percent":"23",
      "dollarAmount":"10350"
    },
    {  
      "product":"3",
      "percent":"20",
      "dollarAmount":"9000"
    },
    {  
      "product":"8",
      "percent":"18",
      "dollarAmount":"8100"
    },
    {  
      "product":"7",
      "percent":"15",
      "dollarAmount":"6750"
    }
  ],
  "InBudget":[  
    {  
      "product":"4",
      "percent":"70",
      "dollarAmount":"7000"
    },
    {  
      "product":"8",
      "percent":"30",
      "dollarAmount":"3000"
    }
  ]
}
1
  • Object does not have the method to access data like this ideal('product') it is showing an error Method does not exist or incorrect signature: void ideal(String)
    – Hunt
    Commented Nov 27, 2019 at 9:16

You must log in to answer this question.

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