2

I need to convert my JSON response to the apex class, but I don't get exact format every time.

{
   "id":"9d7d45a5-2bcb-4ca0-a4d0-d613371c0f22",
   "resource":{
      "id":3,
      "fields":{
         "Field1":{
            "oldValue":2,
            "newValue":3
         },
         "Field2":{
            "oldValue":"2019-10-20T19:33:42.473Z",
            "newValue":"2019-10-21T17:58:20.557Z"
         },
         "Field3":{
            "oldValue":"44Maintenance guidelines for generator unclear",
            "newValue":"44Maintenance guidelines for generator unclear update"
         },
         "Field4":{
            "oldValue":"test desc",
            "newValue":"<div>test desc 123</div>"
         }
..... unknown
          },
          "createdDate":"2019-10-21T17:58:27.9893087Z"
       }
    }

Only modified fields will be provided in the JSON.

How could we build a response class without knowing what field will come?

public class fromJSON{
    public String id;   //9d6d45a5-2bcb-4ba0-a4d0-d613371c7f22
    public cls_resource resource;
    class cls_resource {
        public Integer id;  //3
        public cls_fields fields;
        public String createdDate;  //2019-10-21T17:58:27.9893087Z
    }
    class cls_fields {
        public Field1;
        public Field2;
        public Field3;
        public Field4;
    }
    class Field1{
        public Integer oldValue;    //2
        public Integer newValue;    //3
    }
    class Field2{
        public String oldValue;
        public String newValue;
    }
    class Field3{
        public String oldValue;
        public String newValue;
    }
    class Field4{
        public String oldValue;
        public String newValue;
    }
    class FieldUnkown?{
        public String oldValue;
        public String newValue;
    }
}

1 Answer 1

3

So long as "oldValue" and "newValue" are always String values, you can simply:

public class JsonResponse {
    public class Resource {
        public Integer id;
        Map<String, Map<String, String>> fields;
        public DateTime createdDate;
    }
    public class Response {
        public String id;
        public Resource resouce;
    }
    public static Response parse(String jsonString) {
        return (Response)JSON.deserialize(jsonString, Response.class);
    }
}

Individual data is then accessed by the map:

String oldValue = parsedResponse.response.fields.get('Field1').get('oldValue');

If the data types might include numbers, etc, you will then be forced to write a custom parser, as Object is not supported for automatic deserialization. In that case, you'd have to resort to not using a class at all:

Map<String, Object> responseBase = (Map<String, Object>)JSON.deserialize(payload);
Map<String, Object> resource = (Map<String, Object>)responseBase.get('resource');
Map<String, Object> fields = (Map<String, Object>)resource.get('fields');
for(String fieldName: fields.keySet()) {
  Map<String, Object> values = (Map<String, Object>)fields.get(fieldName);
  System.debug('Field Name: '+fieldName);
  System.debug('Old Value: '+values.get('oldValue');
  System.debug('New Value: '+values.get('newValue');
}
4
  • thanks for your response, I'll try and get back shortly
    – Ragul
    Commented Oct 27, 2019 at 8:44
  • HI @sfdcfox should I have to serialize every time after responseBase ?
    – Ragul
    Commented Oct 27, 2019 at 10:51
  • 1
    @Ragul No, once deserialized, you should be able to get all the values. You'll need to make the appropriate casts (as demonstrated in the answer) to utilize the correct data types.
    – sfdcfox
    Commented Oct 27, 2019 at 15:55
  • But I am still getting the error when inserting numeric values from object
    – Ragul
    Commented Nov 1, 2019 at 9:49

You must log in to answer this question.

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