8

This JSON Apex Class test fails in API 45:

@IsTest
private class SuppressApexObjectNullsTest {
    @IsTest
    static void test() {
        Map<String, Object> m = new Map<String, Object>{
            'x' => 'x',
            'y' => null
        };
        Boolean suppressApexObjectNulls = true;
        System.assertEquals('{"x":"x"}', JSON.serialize(m, suppressApexObjectNulls));
    }
}

returning '{"y":null,"x":"x"}'. Has it ever worked? Or does suppressApexObjectNulls mean something else here?

1
  • 1
    I use this arg all the time but only when the source of the serialize is an Apex custom type; have never tried it on Map<String,Object>. Hmm
    – cropredy
    Commented Jun 12, 2019 at 12:52

2 Answers 2

4

looks like this nulls suppressing works only for custom Apex classes.

I checked it for Sobject, null is serialized:

Contact m = new Contact(
    LastName = 'LastName',
    Email = null
);

Boolean suppressApexObjectNulls = true;
System.assertEquals('{"attributes":{"type":"Contact"},"LastName":"LastName"}', JSON.serialize(m, suppressApexObjectNulls));
// System.AssertException: Assertion Failed: Expected: {"attributes":{"type":"Contact"},"LastName":"LastName"}, Actual: {"attributes":{"type":"Contact"},"LastName":"LastName","Email":null}

for Custom Apex class, null is not serialized

public class Wrapper {
    public String lastName {get; set;}
    public String email {get; set;}
}

Serializing:

Wrapper m = new Wrapper();
m.lastName = 'lastName'; //email here could be explicitly set to null, or null setting can be ommited 

Boolean suppressApexObjectNulls = true;
System.assertEquals('{"lastName":"lastName"}', JSON.serialize(m, suppressApexObjectNulls));
// assert passes
1
  • 2
    Perhaps that explains the rather long parameter name... Pity the detailed description doesn't add some detail. I'll post a link to this as feedback on the documentation page.
    – Keith C
    Commented Jun 12, 2019 at 13:15
5

It works for Apex class Wrappers and SObjects. Probably Apex Runtime thinks that null value to a key is Intentional and doesn't strip it.

class ApexWrapper { String x , y; }

ApexWrapper ap = new ApexWrapper();
ap.x = 'x';
ap.y = null;


Boolean suppressApexObjectNulls = true;
System.assertEquals('{"x":"x"}', JSON.serialize(ap, suppressApexObjectNulls)); //Asserts true

That being said , you can use a custom String Manipulation to strip JSON null.

public static string stripJsonNulls(string JsonString) {

        if (JsonString != null) {
            JsonString = JsonString.replaceAll('\"[^\"]*\":null', ''); //basic removeal of null values
            JsonString = JsonString.replaceAll(',{2,}', ','); //remove duplicate/multiple commas
            JsonString = JsonString.replace('{,', '{'); //prevent opening brace from having a comma after it
            JsonString = JsonString.replace(',}', '}'); //prevent closing brace from having a comma before it
            JsonString = JsonString.replace('[,', '['); //prevent opening bracket from having a comma after it
            JsonString = JsonString.replace(',]', ']'); //prevent closing bracket from having a comma before it
        }

        return JsonString;
    }

You must log in to answer this question.

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