Skip to content

Commit 8de7a33

Browse files
committed
improve null support documentation
1 parent 2f566b8 commit 8de7a33

File tree

2 files changed

+69
-14
lines changed

2 files changed

+69
-14
lines changed

docs/03.reference/01.functions/structkeyexists/function.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ related:
66
- null_support
77
categories:
88
- struct
9+
- decision
910
---
1011

1112
Determines whether a specific key is present in a structure.

docs/recipes/null-support.md

Lines changed: 68 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
<!--
22
{
3-
"title": "Null Support",
3+
"title": "Null Handling in CFML",
44
"id": "null_support",
55
"related": [
66
"function-isnull",
77
"function-nullvalue",
88
"developing-with-lucee-server",
9-
"function-structkeyexists"
9+
"function-structkeyexists",
10+
"function-serializejson",
11+
"function-deserializejson",
12+
"tag-application"
1013
],
11-
"description": "This document explains how to set null support in the Lucee server admin, assigning `null` value for a variable and how to use `null` and `nullvalue`.",
14+
"description": "Understand the differences between partial and full null support - how it affects structKeyExists(), JSON serialization, queries and variable assignment.",
1215
"keywords": [
1316
"Null support",
1417
"null keyword",
@@ -17,30 +20,35 @@
1720
"Lucee"
1821
],
1922
"categories": [
20-
"core"
23+
"core",
24+
"decision"
2125
]
2226
}
2327
-->
2428

25-
# Null Support
29+
# Null Support in CFML
2630

27-
This document explains how to set null support in the Lucee server admin, assigning `null` value for a variable and how to use `null` and `nullvalue`.
31+
CFML supports two null handling modes: partial (default) and full. This recipe explains the behavioural differences and when to use each.
2832

2933
It is an annotation of the video found here: [https://www.youtube.com/watch?v=GSlWfLR8Frs](https://www.youtube.com/watch?v=GSlWfLR8Frs)
3034

3135
## Enabling NULL support
3236

33-
You can enable null support via the **Lucee Server Admin** --> **Language/compiler** and setting Null support to **complete support** (exclusive to Lucee) or **partial support** (default, same as Adobe CF).
37+
You can enable null support via the **Lucee Server Admin** --> **Language/compiler** and setting Null support to **full support** or **partial support** (default).
3438

35-
Or via [[tag-application]]
39+
Per Application via [[tag-application]]
3640

3741
```lucee
3842
this.nullSupport = true;
3943
```
4044

41-
## Explanation
45+
Or toggle dynamically via [[tag-application]]
4246

43-
### Illustration 1:
47+
```lucee
48+
application action="update" nullsupport="true";
49+
```
50+
51+
## Function Return Values
4452

4553
```lucee
4654
<cfscript>
@@ -60,9 +68,9 @@ In this example, the function `test()` does not return a value. This, in effect,
6068

6169
If we assign the function result to a variable, i.e. `t = test();`, and reference the variable, i.e. `dump( t );` an error will be thrown when using **partial support** for null: "the key [T] does not exist". If we enable **full support**, you will be able to reference the variable without error, the dump output will be `Empty: Null` and `IsNull( t )` will evaluate `true`.
6270

63-
In all cases, `dump( isNull( notexisting ) );` will throw an error.
71+
In both modes, `isNull( notexisting )` will return `true` for an undefined variable - the function is specifically designed to safely check for null/undefined values without throwing an error.
6472

65-
### Illustration 2:
73+
## Query Column Values
6674

6775
```luceescript
6876
query datasource="test" name="qry" {
@@ -73,11 +81,12 @@ dump( qry._null );
7381
```
7482

7583
With **partial support** for NULL enabled, `dump(qry._null);` will output an **empty string**.
84+
7685
With **full support**, `Empty: null` will be output and `IsNull( qry._null );` will evaluate `true`.
7786

78-
## NullValue() function and null keyword
87+
## [[function-nullvalue]] and the null keyword
7988

80-
With **partial support** for NULL, the `NullValue()` function must be used to explicitly return a null value (this will work in all scenarios). For example:
89+
With **partial support** for NULL, the [[function-nullvalue]] function must be used to explicitly return a null value (this will work in all scenarios). For example:
8190

8291
```luceescript
8392
var possibleVariable = functionThatMayOrMayNotReturnNull();
@@ -90,3 +99,48 @@ With **full support**, you are able to use the `null` keyword directly and, as i
9099
t = null;
91100
dump( t );
92101
```
102+
103+
## StructKeyExists Behaviour
104+
105+
One of the most significant behavioural differences between partial and full null support is how [[function-structkeyexists]] (and the member function `keyExists()`) handles keys with null values.
106+
107+
With **partial support**, when a struct key holds a null value, [[function-structkeyexists]] returns `false` because the key is effectively removed:
108+
109+
```luceescript
110+
s = { foo: nullValue() };
111+
dump( structKeyExists( s, "foo" ) ); // false
112+
dump( s.keyExists( "foo" ) ); // false
113+
dump( structCount( s ) ); // 0 - the key doesn't exist
114+
```
115+
116+
This standard CFML behaviour can be surprising when you explicitly set a key to null but then can't detect its presence.
117+
118+
With **full support**, keys explicitly set to `null` still exist - they just hold a null value:
119+
120+
```luceescript
121+
s = { foo: null };
122+
dump( structKeyExists( s, "foo" ) ); // true
123+
dump( s.keyExists( "foo" ) ); // true
124+
dump( structCount( s ) ); // 1 - the key exists
125+
dump( isNull( s.foo ) ); // true - but the value is null
126+
```
127+
128+
This allows you to distinguish between "key exists with null value" and "key doesn't exist at all" - which is important when working with APIs, database results, or any scenario where the absence of a key has different meaning than a null value.
129+
130+
## JSON Serialization
131+
132+
With **partial support**, null values in structs are removed before serialization, so they don't appear in the JSON output:
133+
134+
```luceescript
135+
s = { name: "John", middleName: nullValue() };
136+
dump( serializeJSON( s ) ); // {"name":"John"} - middleName is missing
137+
```
138+
139+
With **full support**, null values are properly serialized as JSON `null` via [[function-serializejson]]:
140+
141+
```luceescript
142+
s = { name: "John", middleName: null };
143+
dump( serializeJSON( s ) ); // {"name":"John","middleName":null}
144+
```
145+
146+
This is critical when working with APIs that expect explicit `null` values rather than missing keys.

0 commit comments

Comments
 (0)