Skip to main content
Ben Nadel at NCDevCon 2016 (Raleigh, NC) with: Roger Austin
Ben Nadel at NCDevCon 2016 (Raleigh, NC) with: Roger Austin

Struct Iteration Methods Like Each, Map, And Filter Include Null Values In Lucee CFML 5.3.3.62

By
Published in Comments (6)

Earlier this week, I was working on some reflection-style code in CFML wherein I was recursively looking through structs of data. As I was doing this, it occurred to me that some of the values stored in the structs could be null; and, I wasn't sure off-hand how Lucee would handle these values during iteration. I've already demonstrated that array iteration with null values can be surprising; so, I wanted to take a moment and look at how null values are handled in struct iteration methods (ex, .each, .map, .filter, .every, .reduce) in Lucee CFML 5.3.3.62.

To test this, I created a ColdFusion struct in which one of the values is defined using the nullValue() function. Then, I attempt to iterate over the key-space and examine each iteration value:

<cfscript>

	data = [
		a: 1,
		b: nullValue(),
		c: 3
	];

	data.each(
		( key, value ) => {

			echo( key & " : " );
			// Using the Elvis operator (null coalescing operator) to check whether or
			// not the current iteration value is null.
			echo( value ?: "[null]" );
			echo( "<br />" );

		}
	);

</cfscript>

When we run this ColdFusion code, we get the following output:

A : 1
B : [null]
C : 3

As you can see, the key with the nullValue() value is included in the struct iteration. This code demonstrates the behavior of .each(); however, the same behavior is exhibited in .map(), .filter(), and .reduce().

This behavior isn't entirely surprising. I've written about the handling of null arguments over a decade ago. But, I'm still trying to get a sense of how the CFML language has evolved since I've switched from ColdFusion 10 to Lucee CFML. As such, little sanity checks like this are helpful as I continue to build my mental model.

Want to use code from this post? Check out the license.

Reader Comments

448 Comments

Interestingly:


<cfscript>

function test() {
}

data = [
		a: 1,
		b: test() ?: nullValue(),
		c: 3
	];

	data.each(
		( key, value ) => {

			echo( key & " : " );
			// Using the Elvis operator (null coalescing operator) to check whether or
			// not the current iteration value is null.
			echo( value ?: "[null]" );
			echo( "<br />" );

		}
	);

</cfscript>

Throws an error, even though the function test() should return null. But the following, does not throw an error:


<cfscript>

function test() {
}

t=test();

data = [
		a: isNull(t),
		b: 2,
		c: 3
	];

	data.each(
		( key, value ) => {

			echo( key & " : " );
			// Using the Elvis operator (null coalescing operator) to check whether or
			// not the current iteration value is null.
			echo( value ?: "[null]" );
			echo( "<br />" );

		}
	);

</cfscript>

448 Comments

Apparently, if we enable null support by using lucee server admin --> Language/compiler and setting Null support to complete support, then the first example will not throw an error.

The question is, is it better to use partial null support or complete null support. This is a Lucee only conundrum.

ACF2018 seems to have complete null support.

448 Comments

Sorry.

ACF2018 seems to have partial null support.

Try this test instead:

<cfscript>
	function test() {
	}
	WriteDump(test());
	t=test();
	WriteDump(t);
	WriteDump(isNull(t));
	WriteDump(isNull(notexisting));
</cfscript>

Using both Lucee 5 partial & complete null support & ACF2018!

448 Comments

My first example should have been:


<cfscript>

function test() {
}

t=test();

data = [
		a: 1,
		b: t,
		c: 3
	];

	data.each(
		( key, value ) => {

			echo( key & " : " );
			// Using the Elvis operator (null coalescing operator) to check whether or
			// not the current iteration value is null.
			echo( value ?: "[null]" );
			echo( "<br />" );

		}
	);

</cfscript>

This throws an error in Lucee, but the following does not throw an error in Lucee:


<cfscript>

function test() {
}

data = [
		a: 1,
		b: test(),
		c: 3
	];

	data.each(
		( key, value ) => {

			echo( key & " : " );
			// Using the Elvis operator (null coalescing operator) to check whether or
			// not the current iteration value is null.
			echo( value ?: "[null]" );
			echo( "<br />" );

		}
	);

</cfscript>

So, it seems to be something about assigning null to a variable that causes an issue. Apparently, applying complete null support resolved this issue.

15,848 Comments

@Charles,

This has also tripped me up many times. Technically, there's nothing wrong with null values. What does cause a problem is attempting to reference a null value. I assume this works better when you enable "complete" null support because null becomes a first-class citizen at that point and you can reference a null value just like you would any other value.

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel