You are going to laugh at this, but it turns out that REENCODING as JSON at each step gets you your quoted values. Strange but true!! Try this:
String jsonData = '{"data": {"1500":{"id":"1500","last_name":"Test1"},"298":{"id":"298","last_name":"Test2"}},"status_code":200}';
//get top level map
Map<String,Object> jsonMap = (Map<String, Object>)JSON.deserializeUntyped(jsonData);
//extract data as JSON
String jsonSubset = JSON.serialize(jsonMap.get('data'));
//re-encode as a Map
Map<String,Object> jsonSubsetMap = (Map<String, Object>)JSON.deserializeUntyped(jsonSubset);
MyContact[] contacts = new MyContact[]{};
for (Object obj : jsonSubsetMap.values()){
//re-encode as json, again!
String jsonObj = JSON.serialize(obj);
//deserialize that b@#$ard!!
MyContact contact = (EBTestDeleteMe.MyContact)JSON.deserialize(jsonObj, MyContact.class);
contacts.add(contact);
}
System.debug(contacts);
This outputs:
DEBUG|(MyContact:[id=298, last_name=Test2], MyContact:[id=1500, last_name=Test1])
This assumes you have a class called MyContact
that looks like this:
public class MyContact {
public String id;
public String last_name;
}
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
Try this:
OR
Assuming that
c.TECH_DisplayedErrorJSON__c
has correct json.