1

I am parsing JSON that has field 'next_page'. If this field is null, I do not want to enqueue another HTTP request to fetch that page.

However, in this code, parser.getText() is debugging as null, but not evaluating as null in the if statement.

          if(parser.getText() == 'next_page'){
              parser.nextToken();
              system.debug(parser.getCurrentToken());
                if(parser.getText() != null){
                    System.debug(parser.getText());
                    System.enqueueJob(new fetchURL(parser.getText()));
                }
          }

If I run this code, I see that my debug statement is null, but it is not being evaluated as null in the previous if statement.

I can workaround the issue with:

          if(parser.getText() == 'next_page'){
              parser.nextToken();
              if(parser.getCurrentToken() == JSONToken.VALUE_STRING){
                if(!String.isBlank(parser.getText())){
                    System.debug(parser.getText());
                    System.enqueueJob(new fetchURL(parser.getText()));
                }
              }
          }

I thought the issue might be that Salesforce doesn't allow text fields to be null, but picks up an empty field with String.isBlank however this results in the same problem - null is debugging as null, but not evaluating to null:

if(parser.getText() == 'next_page'){
              parser.nextToken();
              system.debug(parser.getCurrentToken());
                if(!String.isBlank(parser.getText()){
                    System.debug(parser.getText());
                    System.enqueueJob(new fetchURL(parser.getText()));
                }
          }

I've also tried:

      if(parser.getText() == 'next_page'){
              parser.nextToken();
              system.debug(parser.getCurrentToken());
              String parserString = parser.getText();
                if(parserString != null){
                    System.debug(parser.getText());
                    System.enqueueJob(new fetchURL(parser.getText()));
                }
          }

but it seems to assign null to parserString and then not evaluate parserString as null.

Any thoughts? Suggestions? I'm at a loss...

EDIT:

Here is Apex that shows the issue.

    String jsonString = '{"next_page":null,"per_page":30,"page_count":22,"count":654}';

    JSONParser parser = JSON.createParser(jsonString);
    while(parser.nextToken() != null){
        if(parser.getCurrentToken() == JSONToken.FIELD_NAME){
        if(parser.getText() == 'next_page'){
            parser.nextToken();
            system.debug(parser.getText());
            String parserString = parser.getText();
            if(parser.getText() != null){
                System.debug(parser.getText());
            }
        }
    }
}
3
  • 1
    I suspect your JSON: { 'next_page': 'null' } is not the same as { 'next_page': null }. Perhaps someone made a mistake in their JSON?
    – sfdcfox
    Commented Mar 2, 2017 at 23:49
  • thanks for the response, added some code that shows the issue.
    – Aaron M
    Commented Mar 3, 2017 at 0:15
  • Suggest you take a look at using JSON.deserializeStrict instead (or in future), particularly as JSON2Apex will generate the required data holding class for you.
    – Keith C
    Commented Mar 3, 2017 at 9:58

1 Answer 1

3

Use VALUE_NULL token

getText()

Returns the textual representation of the current token or null if there's no current token.

Since you explicitly were calling getText() without checking for null it will convert the null to a text value

String jsonString = '{"next_page":null,"per_page":30,"page_count":22,"count":654}';
JSONParser parser = JSON.createParser(jsonString);
while(parser.nextToken() != null){
    if(parser.getCurrentToken() == JSONToken.FIELD_NAME){
        if(parser.getText() == 'next_page'){
            JSONToken tok = parser.nextToken();
            System.debug('The Token: ' + tok);
            system.debug('First Text Debug' + parser.getText());
            String parserString = parser.getText();
            if(tok != JSONToken.VALUE_NULL){
                System.debug('Inside If test: ' + parser.getText());
            }
        }
    }
}

or simply

String jsonString = '{"next_page":null,"per_page":30,"page_count":22,"count":654}';
JSONParser parser = JSON.createParser(jsonString);
while(parser.nextToken() != null){
    if(parser.getCurrentToken() == JSONToken.FIELD_NAME){
        if(parser.getText() == 'next_page'){
            if(parser.nextToken() != JSONToken.VALUE_NULL){
                System.debug('Inside If test: ' + parser.getText());
            }
        }
    }
}

I rarely user parser unless there are many reserved keywords that I can't easily modify and deserialize. In your case you could simply deserialize into a Map or an Apex class and it would behave as expected

System.debug(JSON.deserializeUntyped(jsonString));

outputs

{count=654, next_page=null, page_count=22, per_page=30}

Much easier to handle

3
  • Huh. The More You Know...
    – sfdcfox
    Commented Mar 3, 2017 at 0:39
  • 1
    +1 advocating deserialize over parse! Nothing worse than inheriting a project that used parse all over the place when deserialize would have done the job in a much more maintainable fashion.
    – dsharrison
    Commented Mar 3, 2017 at 1:25
  • 1
    Thanks ya'll! I thought I'd checked for a JSONToken enum that explained it, but must have missed VALUE_NULL. Will check to see if deserialize works in case D.S. ends up in my codebase someday ;)
    – Aaron M
    Commented Mar 3, 2017 at 1:28

You must log in to answer this question.

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