3

I have multiple-layer predefined classes that JSON.deserialze() can successfully map the JSON data into.

The challenge is in processing the deserialized data. In each layer I need to use if to check whether the class instance is null and the property is null before proceeding.

Is there a better way?

function code:

public void function1(){
  // better way to handle the null check in all these functions?
  if(issueResponse.issues != null && issueResponse.issues[0].id != null)

  // proceed;
}

Class code:

  public class IssueResponse {
    public String startAt;
    public String total;
    public List<Issue> issues;

  }

  public class Issue {
      public String id;
      public String key;
      public Fields fields;
  }

  public class Fields {
    public String summary;
    public IssueType issueType;
    public Assignee assignee;
    public List<FixVersion> fixVersions;
  }

  public class IssueType {
    public String name;
  }

  public class Assignee {
    public String emailAddress;
  }

  public class FixVersion {
    public String name;
  }

2 Answers 2

6

One way to avoid having lots of null checks is to use a Null Object Pattern. In the case of lists, there's an obvious candidate: an empty list. You could use getters to return empty lists instead of nulls e.g.

public class IssueResponse {
    public String startAt;
    public String total;
    public List<Issue> issues {get {
        if(issues == null) {
            issues = new List<Issue>();
        }
        return issues;
    } set;}

}

That certainly makes Lists easier to handle.

You could add accessor methods to your classes so that they offer functionality in terms of what you're trying to achieve. I don't know why you're only looking at the first issue in your code but, supposing the first issue is a special case, make that part of the API of your object and give it a name e.g.

Instead of:

if(issueResponse.issues != null && issueResponse.issues[0].id != null)

Write:

if(issueResponse.hasFirstIssueGotId()) 

If the first one isn't special, then you would probably be doing this in a loop. The fact we can return an empty list means you only have to check thisIssue.Id anyway i.e.

for(Issue thisIssue : issueResponse.issues) {
    if(thisIssue.Id != null) {
    }
}
3
  • If JSON.Desearlizer() automatically initiates empty child nodes when no data is passed in, would this be a good idea and save developer's time?
    – Xi Xiao
    Commented Apr 17, 2019 at 8:28
  • @XiXiao Lots of options might be useful as flags that can alter deserialization behavior. File your suggestion on ideas.salesforce.com.
    – identigral
    Commented Apr 21, 2019 at 18:57
  • It's not clear to me what changes to SF's methods would provide the most help. I use my own library to convert JSON to SObjects with lots of flexibility: bitbucket.org/aidan_harding/jsontosobject/src/master and this library allows you to use the untyped parsing, and then access the data very simply: github.com/open-force/jsonparse. For your purpose here, the second one looks good.
    – Aidan
    Commented Apr 23, 2019 at 10:48
5

With typed deserialization, there's no magic in SF platform that will transform nulls into something else. The null check must be made somewhere in your code or you have to catch an instance of NullPointerException and act accordingly.

You can make it a little more palatable by encapsulating the behavior in your class via an Apex property:

public class IssueResponse {
  public List<Issue> issues {
     get {
        return issues == null ? new List<Issue>() : issues;
     }
  }
}

The instantiation of an empty List as a way to avoid a null pointer is an example, your code might need to do something else.

1
  • Except this might get a ListException (out of bounds) in the original code; you would want to initialize the list with a non-null element in this case.
    – sfdcfox
    Commented Apr 10, 2019 at 13:46

You must log in to answer this question.

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