This article explains why you cannot use the traditional NULL value with ArduinoJson.

The problem with NULL

As I explained in the article Why C++ programmers don’t use NULL?, C++ defines NULL like that:

#define NULL 0

As you can see, NULL is not a pointer: it’s an integer.

So, when you write NULL in your program, all ArduinoJson sees is a 0.

Example with serialization

Suppose you wrote the following program:

StaticJsonDocument<128> doc;
doc["value"] = NULL;
serializeJson(doc, Serial);

You probably expect to see the following line in the Serial Monitor:

{"value":null}

However, since NULL is really 0, you’ll see this instead:

{"value":0}

Example with deserialization

Suppose you have the following input:

{"a":0,"b":null}

Take the following program:

StaticJsonDocument<128> doc;
deserializeJson(doc, input);

if (doc["a"] == NULL)
  Serial.println("a == null");
else
  Serial.println("a != null");

if (doc["b"] == NULL)
  Serial.println("b == null");
else
  Serial.println("b != null");

If you run this program, you’ll get the following output in the Serial Monitor:

a == null
b != null

In other words, you’ll get the exact opposite of what you expected.

The solution

As I explained in the article Why C++ programmers don’t use NULL?, the best solution is to replace NULL with the keyword nullptr introduced in C++11.

Because nullptr has a dedicated type (it’s a pointer, not an int), ArduinoJson understands what you mean and implements the expected behavior.

Example with serialization

Suppose we upgrade our previous example like this:

StaticJsonDocument<128> doc;
doc["value"] = nullptr;
serializeJson(doc, Serial);

As expected, the program prints the following line in the Serial Monitor:

{"value":null}

Example with deserialization

Suppose you still have the following input:

{"a":0,"b":null}

We can upgrade the original program like this:

StaticJsonDocument<128> doc;
deserializeJson(doc, input);

if (doc["a"] == nullptr)
  Serial.println("a == null");
else
  Serial.println("a != null");

if (doc["b"] == nullptr)
  Serial.println("b == null");
else
  Serial.println("b != null");

As expected, you’ll see the following lines in the Serial Monitor:

a != null
b == null

When C++11 is not available

If your compiler doesn’t support nullptr, you can use one of the two following workarounds.

Option 1: use isNull()

You can use JsonVariant::isNull() to test if a value is null:

if (doc["a"].isNull())
  Serial.println("a == null");
else
  Serial.println("a != null");

Option 2: use a null pointer

To insert null in a JSON document, you must pass a pointer. Even if nullptr is not available, you can still pass a null pointer like this:

doc["value"] = (char*)0;

Alternatively, you can define your own null pointer constant like this:

const char* const null = 0;

doc["value"] = null;

See also

Global warming stripes by Professor Ed Hawkins (University of Reading)