Skip to main content
Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.

The Elvis / Null Coalescing Operator Can Sometimes Replace The Safe Navigation Operator In Lucee CFML 5.3.6.61

By Ben Nadel on
Tags: ColdFusion

Yesterday, when I was listening to the latest episode of the Modernize or Die Podcast, Brad Wood said something that I had not heard before: that the Safe Navigation operator can usually be replaced with the Elvis / Null Coalescing operator in Lucee CFML. I had always just assumed that without the safe navigation syntax, undefined keys would still throw null-reference errors, regardless of whether or not the Elvis operator was involved. As it turns out, Brad was right! Though, it only works if the given expression does not contain a method call. Since this was news to me, I thought it was worth a quick demo in Lucee CFML 5.3.6.61.

As a quick recap, the Safe Navigation operator allows you to safely traverse an object graph without throwing null-reference errors by using ?. instead of . when drilling down through object keys:

foo?.bar?.baz

If any of the keys along the way do not exist, the overall expression returns null instead of throwing an error.

The Elvis / Null Coalescing operator (?:), on the other hand, allows you to provide a fallback value for an expression that returns a null value:

foo?.bar?.baz ?: "fallback value"

Now, what Brad is saying is that in this previous expression, I can actually remove the Safe Navigation operator and just use the Elvis operator. To demonstrate, here's a tiny ColdFusion script:

<cfscript>

	echo( "Foo exists: " & variables.keyExists( "foo" ) );
	echo( ". " );

	echo( foo.bar.baz ?: "Null value fallback" );

</cfscript>

In this small demo, foo doesn't exist. And, it's where I would normally use the Safe Navigation operator. However, since we are also including the Elvis operator, the previous ColdFusion script results in the following output:

Foo exists: false. Null value fallback

As you can see, even though foo doesn't exist, we can still side-step null reference errors by using the Elvis operator to provide a fallback value.

This is pretty cool! But, be aware that it appears to breakdown if the left-hand expression contains a method call. For example, if we call this ColdFusion code:

<cfscript>

	echo( "Foo exists: " & variables.keyExists( "foo" ) );
	echo( ". " );

	echo( foo.bar.baz() ?: "Null value fallback" );

</cfscript>

... which is the same as above, except that our last object reference is .baz(), not .baz, we get the following ColdFusion error:

variable [foo] doesn't exist

It doesn't matter that the Method invocation operator (()) is on the last object reference - it could be anywhere in the left-hand expression and the outcome is the same.

This is true even if the method being invoked exists:

<cfscript>

	echo( foo().bar.baz ?: "Null value fallback" );

	// ------------------------------------------------------------------------------- //
	// ------------------------------------------------------------------------------- //

	public void function foo() {
		// No-op.
	}

</cfscript>

In this case, the foo() function exists, but returns null. And, when we run this code, we get the following ColdFusion error:

No matching property [bar] found

It's really cool that the Elvis operator can stand-in, so to speak, for the Safe Navigation / Null Coalescing operator in simple expressions - thanks Brad! However, just be aware that this does break down in more complex expressions. Of course, you can always use the Safe Navigation operation in conjunction with the Elvis operator in those cases.



Reader Comments

I've forever wished I could use JS syntax for this...

foo.bar.baz || "Null value fallback"

I hadn't considered using the elvis operator to mimic this behavior. Cleaver. Unfortunately, it does not work in Adobe CF. Another (useful) example of where Lucee shines.

Reply to this Comment

@Zac,

Ha ha :D Not this time.

@Chris,

Yeah, Lucee CFML is pretty grand. That said, the safe-navigation operator is in TypeScript if you ever go that route for your JavaScript.

Reply to this Comment

Post A Comment

You — Get Out Of My Dreams, Get Into My Blog
Live in the Now
Oops!
NEW: Some basic markdown formatting is now supported: bold, italic, blockquotes, lists, fenced code-blocks. Read more about markdown syntax »
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.