Your output is a single class according to the json I see and not a list.
List<Study> result =(List<Study>)JSON.deserialize(this.studyJson , List<Study>.class);
You shoud expect either a class or turn json output into alist of study objects by adding []
Regarding the event_data
issue: your JSON is inconsistent. In one case it's an object containing the user_agent
string:
"event_data": {
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36"
},
And elsewhere it's a list of quiz_data
:
"event_data": [
{
"quiz_question_id": "220",
"answer": null
},
{
"quiz_question_id": "221",
"answer": []
} [...]
],
This wouldn't be picked up by a JSON linter, because it's just checking that the data is valid - not that it's consistent.
I notice that the parser code generated by JSON2Apex is different from your parser code above, and e.g. creates different classes to handle the different types of answers
and event_data
:
//
// Generated by JSON2Apex http://json2apex.herokuapp.com/
//
public class JSON2Apex {
public class Answers {
public String answer_exact;
public String answer_error_margin;
public String answer_range_start;
public String answer_range_end;
public String answer_weight;
public String numerical_answer_type;
public String blank_id;
public String id;
public String match_id;
public String answer_text;
public String answer_match_left;
public String answer_match_right;
public String answer_comment;
public String answer_html;
public String answer_match_left_html;
public String answer_comment_html;
}
public class Quiz_data {
public Integer id;
public String regrade_option;
public Integer points_possible;
public String correct_comments;
public String incorrect_comments;
public String neutral_comments;
public String correct_comments_html;
public String incorrect_comments_html;
public String neutral_comments_html;
public String question_type;
public String question_name;
public String name;
public String question_text;
public List<Answers> answers;
public String text_after_answers;
public Integer assessment_question_id;
public Integer position;
public String published_at;
}
public class Answers_Z {
public String id;
public String text;
public String comments;
public String comments_html;
public Integer weight;
public String html;
}
public class Quiz_submission_events {
public String id;
public String event_type;
public Event_data event_data;
public String created_at;
}
public List<Quiz_submission_events> quiz_submission_events;
public class Event_data {
public Integer quiz_version;
public List<Quiz_data> quiz_data;
}
public class Answers_Y {
public Integer id;
public String text;
public String html;
public String comments;
public String comments_html;
public Integer weight;
}
public class Answers_X {
}
public class Event_data_Z {
public String user_agent;
}
public class Event_data_Y {
public String quiz_question_id;
public Object answer;
}
public static JSON2Apex parse(String json) {
return (JSON2Apex) System.JSON.deserialize(json, JSON2Apex.class);
}
}
This is an attempt to handle the inconsistencies in the JSON. I'm not sure whether it'll actually work in practice, but it's worth trying.
If it doesn't work, you have a few options.
- Ideally you would change the JSON to be consistent, but that may not be an option if you're receiving it from a third party.
- Alternatively, you could use
JSON.deserializeUntyped()
and check the type of each event_data
at runtime, but you'd lose the advantages of typed deserialization.
- Or, you could write custom parser code to manually check the value of
event_data
and parse it appropriately. If you check the Create explicit parse code
box on JSON2Apex, you can take the parser code as a starting point.
Best Answer
JSON should have following format: