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@email.com",
        "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":"otheremail@email.com",
        "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!!!

  • 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!! – user7484388 Mar 14 '19 at 23:20
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)

  • 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!! – user7484388 Mar 14 '19 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!

  • Thank you for you help!! I'm back in business. :) – user7484388 Mar 14 '19 at 23:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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