2

I am using session variables in Coldfusion 2018 and I am trying to figure out how to add a variable with the way my if statements are set up.

<cfif isDefined("session")
            and structKeyExists(session, 'checkout')
                and structKeyExists(session.checkout, 'info')
                    and structKeyExists(session.checkout.info, 'andor_1') >
        <cfif session.checkout.info.andor_1 eq "And">
      <strong>- All signatures are required.</strong>
      </cfif>
      </cfif>

or 

<cfif isDefined("session")
            and structKeyExists(session, 'checkout')
                and structKeyExists(session.checkout, 'info')
                    and structKeyExists(session.checkout.info, 'bandor_1') >
        <cfif session.checkout.info.bandor_1 eq "And">
      <strong>- All signatures are required.</strong>
      </cfif>
      </cfif>

The if statements are almost identical andor_1 or bandor_1 but either one might not always exist which is why I am using the isDefined.

I have tried using || and or.

 <cfif isDefined("session")
                and structKeyExists(session, 'checkout')
                    and structKeyExists(session.checkout, 'info')
                        and structKeyExists(session.checkout.info, 'andor_1') 
|| isDefined("session")
                and structKeyExists(session, 'checkout')
                    and structKeyExists(session.checkout, 'info')
                        and structKeyExists(session.checkout.info, 'bandor_1')>
            <cfif session.checkout.info.andor_1 eq "And" || session.checkout.info.bandor_1 eq "And">
          <strong>- All signatures are required.</strong>
          </cfif>
          </cfif>

Any help combining these cfifs would be greatly appreciated.

Shawn
  • 4,758
  • 1
  • 20
  • 29
David Brierton
  • 6,977
  • 12
  • 47
  • 104
  • What version of ColdFusion? – Shawn Dec 05 '18 at 23:37
  • Coldfusion 2018 – David Brierton Dec 06 '18 at 13:40
  • 1
    With CF2018, I'd definitely switch to cfscript syntax, since you're working on a modern version of CF. And for this I'd use the safe navigation operator. This is essentially the purpose of this operator. For `OR`, the `||` operator _can_ be used in a `cfif` tag, but it looks much less out of place in script. :-) – Shawn Dec 06 '18 at 16:37
  • I'd recommend considering the elvis ?: operator. It saves a lot of hassle for deep nested structs. – Scott Jibben Dec 06 '18 at 19:04

3 Answers3

3

The correct way in CF is 'OR' as opposed to ||.

However, in your first example you've place the "OR" outside of your IF statements. Try this:

 <cfif isDefined("session") AND structKeyExists(session, 'checkout') AND structKeyExists(session.checkout, 'info')
                AND (
                        (structKeyExists(session.checkout.info, 'andor_1') AND session.checkout.info.andor_1 eq "And")
                        OR
                        (structKeyExists(session.checkout.info, 'bandor_1') AND session.checkout.info.bandor_1 eq "And")
                    )>

     <strong>- All signatures are required.</strong>
</cfif>
CFMLBread
  • 734
  • 3
  • 7
  • 1
    `||` will work in cfscript. CFTags are a little less flexible. But in CF2016+, Safe Navigation Operator can also be used in tags. `.....` – Shawn Dec 06 '18 at 00:04
  • 1
    `||` is supported in ColdFusion since CF8 (including CFML). – Seanvm Dec 06 '18 at 06:45
3

If you are using CF2016, you can use the Safe Navigation Operator, or ?. (https://www.adobe.com/devnet/coldfusion/articles/language-enhancements-cf-2016.html). And you should also start using cfscript for these kinds of logic things.

<cfscript>
// Setup my struct. Session is a struct. I renamed it for my example since it's a special word.
s = {
    checkout : {
        info : { 
            andor_1 : "And" , 
            bndor_1 : "And" 
        }
    }
} ;

//writeDump(session);

// If CF2016+ Safe Navigation Operator To The Rescue!

if( s?.checkout?.info?.andor_1 == "And" || s?.checkout?.info?.bndor_1 == "And" ) {
  writeOutput("<strong>- All signatures are required.</strong>");
}
</cfscript>

https://trycf.com/gist/a82b8466c427fb40b53bbc506e4d419d/lucee5?theme=monokai

Shawn
  • 4,758
  • 1
  • 20
  • 29
2

Another option (although less performant than using structKeyExists().

<cfif isDefined("session.checkout.info.andor_1") AND session.checkout.info.andor_1 eq "And" 
  OR isDefined("session.checkout.info.bandor_1") AND session.checkout.info.andor_1 eq "And">

  <strong>- All signatures are required.</strong>
</cfif>

Something to look into would be setting some default values so that you don't need to run isDefined or structKeyExists checks. That has the potential to clean up your code quite a bit and make it more readable.

There are of course going to be exceptions or scenarios where they are necessary (e.g. consuming a response from an API).

Seanvm
  • 394
  • 1
  • 9
  • 1
    Good call on the code reduction, but you can still use `StructKeyExists` instead of `IsDefined`. You also owe me a beer for voting your reputation into triple digits. – Dan Bracuk Dec 06 '18 at 19:08