0

I have a wrapper class written in following manner

class Wrapper{
    String name {get;set;}
    Integer age {get;set;}
    EduWrap edu {get;set;}

    public String returnTest(){
        return 'YAY !';
    }
}

class EduWrap{
    Integer a1;
    Integer a2;
}

I deserialize a JSON into type wrapper as follows :

Wrapper wrap = (Wrapper)JSON.deserialize(test, Wrapper.class); // 'test' is the json string

If I wanted to check if all the fields of 'wrap' weren't null, how could I do it instead of manually checking each and every field ? (Assuming there are more variables declared inside 'wrap')

If this was an SObject, maintaining a set of fields and then checking for null using get() while iterating for each of the fields in the set would allow me to perform null checks. Please suggest me ways of doing something similar/better for this situation.

  • After that, what do want to do? This is important to know because approach may change based on goal? – Ayub Apr 8 at 13:10
  • @Ayub I intend to compile a list of fields that are null and generate a response back to the caller. – N_H1922 Apr 8 at 13:25
2

You can provide a method that returns fields in a Map and a method that checks the map for null fields:

class Wrapper{
    String name {get;set;}
    Integer age {get;set;}
    EduWrap edu {get;set;}

    public Map<String, Object> toMap() {
           return (Map<String, Object>) JSON.deserializeUntyped(JSON.serialize(this));
    }

   public Boolean hasNullField() {
     for (Object curr : this.toMap().values()) {
         if (curr == null) {
             return true;
         }
     }
     return false;
   }
}

| improve this answer | |
1

Above given solution works as expected but I don't find it very efficient in the terms of performance:

  1. Each serialize/deserialize takes a lot of execution time. Here we are doing it 3 times.
  2. After deserialization, we need to run for loop. That would take O(n) in worst case.

I would prefer get advantage of get;set properties like below however I need to add extra code little bit and work only if all JSON response is consistent (means always return a key whether it has value or not), but it would be efficient:

public class Wrapper{
    public Boolean havingNull;
    String name {
        get{ return name;} 
        set{ if(String.isBlank(value))havingNull = true; name = value;}
    }

    Integer age {get;set;}
    EduWrap edu {get;set;}


    public String returnTest(){
        return 'YAY !';
    }
    public class EduWrap{
        Integer a1;
        Integer a2;
    }
}

Example:

String s = '{"name":"","age":26,"edu":{"a1":1, "a2":2}}';
Wrapper wrap = (Wrapper)JSON.deserialize(s, Wrapper.class);
system.debug(wrap.havingNull);
| improve this answer | |
  • If I use your code with the JSON as '{"age":26,"edu":{"a1":1, "a2":2}}', I get the debug as null.If a particular parameter is not included in the rest, I would want it to be considered as a null because I have to later return a list of parameters that were null or not included in the json. – N_H1922 Apr 8 at 17:45
  • But if you key is not present in json, it would not produce the result. Even First approach would not have the key in Map. This is very different scenario and we may need to iterate over values to know which field is not given or use "deserializeStrict" and remake the call if it fails – Ayub Apr 8 at 18:00
  • For some reason if I put 'System.debug(this.toMap().values());' right at the beginning of hasNullField()of the first approach, I see null in the log when I omit the name key from the request. I had used deserializeStrict and it used to fail only in times an additional key was added to the JSON which was not a part of the wrapper. For omitted keys, the results were same as the basic deserialize. – N_H1922 Apr 8 at 18:11
  • Need to work if I can get it working using this approach. U can use the first approach till then. Updated answer to explain this scenario. – Ayub Apr 8 at 18:49
  • 1
    Adding an if statement in every setter method, it will give you a cost of O(n). Unless you don't want to count it:) I agree that the roundtrip of json de/serialisation has a cost but imagine the scenario that you want to add more fields or you have more json objects. At least toMap/hasNull can be easily inherited. You have to decide if you will sacrifice a bit of performance to win the boilerplate code of each getter on every class. – kvor Apr 20 at 13:21

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.