0

Salesforce rockstars!

I'm in need of some help, and thank you in advance for taking the time to review my question! I'm pretty new to Java/Apex, and most of the work I do is with internal Salesforce data. I've recently gotten a request to work with an external SurveyMonkey API (yay!!). I've gotten the callout to return a JSON response, but I can't quite figure out where I'm going wrong on trying to parse the JSON. Here's an example of the JSON containing a list of 2 survey responses (sorry if it's super long!):

 { 
    "per_page":100,
    "total":2,
    "data":[ 
     { 
       "total_time":64,
       "href":"https:\/\/api.surveymonkey.com\/v3\/surveys\/123\/responses\/123",
       "custom_variables":{ 
        "Email":"[email protected]",
        "sObjID":"012345asnsdsf"
       },
       "ip_address":"01.01.01.01",
       "id":"000001234",
       "logic_path":{ 

       },
       "date_modified":"2019-03-11T16:05:15+00:00",
       "response_status":"completed",
       "custom_value":"",
       "analyze_url":"https:\/\/www.surveymonkey.com\/analyze\/browse\/806Jit6q?respondent_id=123456",
       "pages":[ 
        { 
          "id":"89247584",
          "questions":[ 

          ]
        },
        { 
          "id":"439410",
          "questions":[ 
           { 
             "id":"98350948",
             "answers":[ 
              { 
                "choice_id":"8290348"
              },
              { 
                "choice_id":"493045"
              },
              { 
                "choice_id":"084058"
              }
             ]
           }
          ]
        },
        { 
          "id":"238904890",
          "questions":[ 
           { 
             "id":"9045234",
             "answers":[ 
              { 
                "choice_id":"6096678"
              }
             ]
           }
          ]
        }
       ],
       "page_path":[ 

       ],
       "recipient_id":"",
       "collector_id":"87897897897",
       "date_created":"2019-03-11T16:04:11+00:00",
       "survey_id":"168978947",
       "collection_mode":"default",
       "edit_url":"https:\/\/www.surveymonkey.com\/r\/?sm=57IXeTgm0ZvS5qKhb",
       "metadata":{ 

       }
     },
     { 
       "total_time":84,
       "href":"https:\/\/api.surveymonkey.com\/v3\/surveys\/16847\/responses\/1012302",
       "custom_variables":{ 
        "Email":"[email protected]",
        "sObjID":"0000234834sdfksdfk"
       },
       "ip_address":"02.02.02.02",
       "id":"194590283490",
       "logic_path":{ 

       },
       "date_modified":"2019-03-11T16:31:32+00:00",
       "response_status":"completed",
       "custom_value":"",
       "analyze_url":"https:\/\/www.surveymonkey.com\/analyze\/browse\/bOvVxh?respondent_id=13452302",
       "pages":[ 
        { 
          "id":"6908908",
          "questions":[ 

          ]
        },
        { 
          "id":"6299890890",
          "questions":[ 
           { 
             "id":"2390890061",
             "answers":[ 
              { 
                "choice_id":"160989089055"
              },
              { 
                "choice_id":"1618908908857"
              },
              { 
                "choice_id":"1098903858"
              }
             ]
           }
          ]
        },
        { 
          "id":"6267567341",
          "questions":[ 
           { 
             "id":"2376567323",
             "answers":[ 
              { 
                "text":"Jane Doe"
              }
             ]
           }
          ]
        }
       ],
       "page_path":[ 

       ],
       "recipient_id":"",
       "collector_id":"227798789",
       "date_created":"2019-03-11T16:30:08+00:00",
       "survey_id":"89789",
       "collection_mode":"default",
       "edit_url":"https:\/\/www.surveymonkey.com\/r\/?sm=9_2FgDW9",
       "metadata":{ 

       }
     }
    ],
    "page":1,
    "links":{ 
     "self":"https:\/\/api.surveymonkey.net\/v3\/surveys\/1234\/responses\/bulk?page=1&per_page=100"
    }
  }

And here's the Apex that JSON2APEX generated for me (and I can't quite figure out technically how all the class/inner classes here end up with values in the variables, but I suppose I'll save that dark magic for another day).:

public class SurveyMonkeyResponses 
  {

    public class Pages {
      public String id;
      public List<Logic_path> questions;
    }

    public class Answers {
      public String choice_id;
    }

    public class Answers_Z {
      public String text;
    }

    public Integer per_page;
    public Integer total;
    public List<Data> data;
    public Integer page;
    public Links links;

    public class Logic_path {
    }

    public class Links {
      public String self;
    }

    public class Questions {
      public String id;
      public List<Answers> answers;
    }

    public class Data {
      public Integer total_time;
      public String href;
      public Custom_variables custom_variables;
      public String ip_address;
      public String id;
      public Logic_path logic_path;
      public String date_modified;
      public String response_status;
      public String custom_value;
      public String analyze_url;
      public List<Pages> pages;
      public List<Logic_path> page_path;
      public String recipient_id;
      public String collector_id;
      public String date_created;
      public String survey_id;
      public String collection_mode;
      public String edit_url;
      public Logic_path metadata;
    }

    public class Custom_variables {
      public String Email;
      public String sObjID;
    }

    public class Questions_Z {
      public String id;
      public List<Answers_Z> answers;
    }


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

And then finally, I start debugging a bit to check for some of the values, which seems to work at first, but then I start running into errors:

    //
    //Code block for making the request
    //

    IF (response.getStatusCode() == 200) {

    SurveyMonkeyResponses resps = (SurveyMonkeyResponses) SurveyMonkeyResponses.parse(response.getBody());

      //Returns all the key:value pairs I'd expect
      //Except for Logic_path:[] shown on the next debug
      system.debug(resps.Data[0]);

      //Returns Pages:[id=439410, questions=(Logic_path:[])]
      //But not sure where (Logic_path:[]) is coming from
      system.debug(resps.Data[0].pages[1]);

      //Returns the expected ID 439410
      system.debug(resps.Data[0].pages[1].id);

      //Only returns Logic_path:[]
      system.debug(resps.Data[0].pages[1].questions[0]);

      //Error: Variable does not exist: id
      system.debug(resps.Data[0].pages[1].questions[0].id);

      //Error: Variable does not exist: answers
      system.debug(resps.Data[0].pages[1].questions[0].answers);
    }

It seems like I'm kind of close, but I can't tell if I'm using this correctly or if I'm barking up the wrong tree. I also tried changing the SurveyMonkeyResponses method to be:

public static LIST<SurveyMonkeyResponses> parse(String json) {
  return (LIST<SurveyMonkeyResponses>) System.JSON.deserialize(json, LIST<SurveyMonkeyResponses>.class); 

But I got the error: System.JSONException: Malformed JSON: Expected '[' at the beginning of List/Set And then I tried to trim the text that precedes the first [ character to try and get it to recognize the JSON as a list, but ended up with the following when I debug logged the results:

  (SurveyMonkeyResponses:[data=null, links=null, page=null, per_page=null, total=null], SurveyMonkeyResponses:[data=null, links=null, page=null, per_page=null, total=null])

Thanks a million for helping to point me in the right direction!!!

1
  • Thank you both very much!! After looking at your recommendations something just "clicked" and the SurveyMonkeyResponses class suddenly made sense to me. I also had to change a few other small things in that file that didn't seem to map correctly, and also commented out page_path and logic_path because they were still causing trouble (but I didn't figure out why) and I don't need them, and now all is well. Thank you both very much!! Commented Mar 14, 2019 at 23:20

2 Answers 2

0

The problem is the conflicting classes Questions and Answers. I expect you would want to use "explicit parsing mode" to get this working correctly. However, there's an even easier fix. Merge Answers_Z and Questions_Z to the other class, then replace the reference. The following should work:

public class SurveyMonkeyResponses 
  {

    public class Pages {
      public String id;
      public List<Logic_path> questions;
    }

    public class Answers {
      public String choice_id;
      public String text;
    }

    public Integer per_page;
    public Integer total;
    public List<Data> data;
    public Integer page;
    public Links links;

    public class Logic_path {
    }

    public class Links {
      public String self;
    }

    // Merged this together
    public class Questions {
      public String id;
      public List<Answers> answers;
    }

    public class Data {
      public Integer total_time;
      public String href;
      public Custom_variables custom_variables;
      public String ip_address;
      public String id;
      public Logic_path logic_path;
      public String date_modified;
      public String response_status;
      public String custom_value;
      public String analyze_url;
      public List<Pages> pages;
      public List<Logic_path> page_path;
      public String recipient_id;
      public String collector_id;
      public String date_created;
      public String survey_id;
      public String collection_mode;
      public String edit_url;
      public Logic_path metadata;
    }

    public class Custom_variables {
      public String Email;
      public String sObjID;
    }



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

(note: there may still be other errors, but hopefully this should get you closer to your ideal solution)

1
  • Thank you, @sfdcfox!! Seeing you merge one of the inner classes into another class made a light bulb go off for me, and suddenly what I had been staring at endlessly made sense for how all of the pieces fit together. Much appreciated!! Commented Mar 14, 2019 at 23:22
0

Looks like the only problematic part in your code is:

public class Pages {
  public String id;
  public List<Logic_path> questions;
}

replace public List<Logic_path> questions with:

public List<Questions> questions;

let me know if it works or you needed this to work in any other way!

1
  • Thank you for you help!! I'm back in business. :) Commented Mar 14, 2019 at 23:20

You must log in to answer this question.

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