Use of IS outside of <cfif> - coldfusion

I am not quite sure what this does.
<cfset User.ZeroBDK = FORM.ZeroBDK is "YES">
Is this short hand for
<cfset User.ZeroBDK = false>
<cfif FORM.ZeroBDK EQ "Yes">
<cfset User.ZeroBDK = true>
</cfif>
Are there other truthy things that get set to true?

The (FORM.ZeroBDK is "YES") expression will evaluate to true or false depending on what is in FORM.ZeroBDK,
so <cfset User.ZeroBDK = FORM.ZeroBDK is "YES">
will give to User.ZeroBDK a boolean value of true or false.
I'm just speculating..., but if you got this from some legacy code, it seems like not the best way to determine if FORM.ZeroBDK has something in it.

Related

Parse the contents of a Coldfusion variable into separate variables

OK, so I've been banging my head against this one for a while and getting nowhere. I've been attempting to take the contents of a variable and parse the contained string into parts that would then be ingested into 5 separate variables. Seems simple enough right? Well, it has not proven to be simple at all, at least for me.
So I have a variable (PageContent) that contains the trimmed content from a CFHTTP request.
The PageContent variable now contains:
<tdnowrapalign=right>07/18/2020 13:00</td>
<tdalign=right>1002.12</td>
<tdalign=right>2,874,887</td>
<tdalign=right>12,766</td>
<tdalign=right>13,038</td>
It seems like there should be an easy way to write a loop that would loop over the tags in the "PageContent" variable assigning the content of each tag to a different variable. But every way I try to parse the data in the variable I either get an error (Complex object types cannot be converted to simple values.) or I end up with the content that I originally had in the "PageContent" variable repeated within the loop.
For instance, if I had a loop that would run through 5 iterations and could grab the contents of the tags assigning each to a variable then the desired result would be:
DateTime = "07/18/2020 13:00"
Elevation = "1002.12"
Storage = "2,874,887"
Outflow = "12,766"
Inflow = "13,038"
After trying every example I could find here and elsewhere online I'm now on something like my 100th attempt. Now I'm trying to use regular expressions to grab the contents of the tags and assign them to variables but no luck there. What I ended up with was the entire contents of the PageContent variable being stuffed into each one of the variables. The result was not really unexpected since I don't know of a way to differentiate between the 3 identical "tdalign" tags, but still it seems like at least the first variable would have worked since the tag was different "tdnowrapalign".
<cfset i=5/>
<cfloop index = "LoopCount" from = "1" to = #i#>
<cfif i EQ 1>
<cfset dataDateTime = Replace(PageContent, "<[tdnowrapalign][^>]*>(.+?)</[td]>","","ALL")>
<cfelseif i EQ 2>
<cfset elevation = Replace(PageContent, "<[tdalign][^>]*>(.+?)</[td]>","","ALL")>
<cfelseif i EQ 3>
<cfset storage = Replace(PageContent, "<[tdalign][^>]*>(.+?)</[td]>","","ALL")>
<cfelseif i EQ 4>
<cfset outflow = Replace(PageContent, "<[tdalign][^>]*>(.+?)</[td]>","","ALL")>
<cfelseif i EQ 5>
<cfset inflow = Replace(PageContent, "<[tdalign][^>]*>(.+?)</[td]>","","ALL")>
</cfif>
<cfoutput>
<cfif isdefined("dataDateTime")>
dataDateTime = #dataDateTime#<br>
</cfif>
<cfif isdefined("elevation")>
elevation = #elevation#<br>
</cfif>
<cfif isdefined("storage")>
storage = #storage#<br>
</cfif>
<cfif isdefined("outflow")>
outflow = #outflow#<br>
</cfif>
<cfif isdefined("inflow")>
inflow = #inflow#<br>
</cfif>
</cfoutput>
<cfset i = i - 1>
</cfloop>
Does anyone know if there is a way to get to the desired outcome I described where I end up with 5 variables containing the contents of the tags contained within the "PageContent" variable?
One way of doing it would be like this
<cfset PageContent = '<tdnowrapalign=right>07/18/2020 13:00</td>
<tdalign=right>1002.12</td>
<tdalign=right>2,874,887</td>
<tdalign=right>12,766</td>
<tdalign=right>13,038</td>' />
<cfset data = ListToArray(PageContent, '</td>', false, true) />
<cfset DateTime = ListLast(data[1], '>') />
<cfset Elevation = ListLast(data[2], '>') />
<cfset Storage = ListLast(data[3], '>') />
<cfset Outflow = ListLast(data[4], '>') />
<cfset Inflow = ListLast(data[5], '>') />
Demo: https://trycf.com/gist/b4f3b630bd1cbdc505d07a7d79b68ef5/acf?theme=monokai

Convert name value pairs to struct

It's been awhile since I've written this type of ColdFusion code, hence the question.
I am returning values from a .NET webservice into ColdFusion. The webservice returns an array of strings. The following code...
<cfoutput>
<cfset xArrayItems=#GetRequestedUserSettings.settingValues.getString()#>
<cfset xLen=ArrayLen(GetRequestedUserSettings.settingValues.getString())>
<cfloop index="x" from=1 to="#xLen#">
#xArrayItems[x]#<br />
</cfloop>
</cfoutput>
results in the following output ...
maxsize=50
isdomainadmin=False
seenwelcome=False
I want to put those name/value pairs into a meaningful structure so that I can reference them farther down in the code. I actually need to pass them in as a cfinvokearguments for the next webservice call.
Could someone please be kind enough to remind me how to do this in CF8? Most of what I am finding refers to newer versions.
I ended up with something quite similar to what #Henry you provided.
<cfset UserSettings = structNew()>
<cfset xArrayItems= GetRequestedUserSettings.settingValues.getString()>
<cfset xLen=ArrayLen(GetRequestedUserSettings.settingValues.getString())>
<cfloop index="x" from=1 to="#xLen#">
<cfset varName = ListGetAt(xArrayItems[x], 1, "=")>
<cfset varValue = ListGetAt(xArrayItems[x], 2, "=")>
<cfset "UserSettings.#varname#" = varValue>
</cfloop>
Not sure if an Array or a Struct is a better solution, but the both work in the end.
Slightly more readable version I can come up with that will work with CF8:
<cfset UserSettings = {}>
<cfset xArrayItems = GetRequestedUserSettings.settingValues.getString()>
<cfloop array="#xArrayItems#" index="item">
<cfset varname = ListFirst(item, "=")>
<cfset varvalue = ListRest(item, "=")>
<cfset UserSettings[varname] = varvalue>
</cfloop>

Coldfusion 10 cfloop errors

I am getting an error after upgrade from coldfusionOX to coldfusion 10.
Error Occurred While Processing Request Complex object types cannot be
converted to simple values.
The expression has requested a variable or an intermediate expression
result as a simple value. However, the result cannot be converted to a
simple value. Simple values are strings, numbers, boolean values, and
date/time values. Queries, arrays, and COM objects are examples of
complex values. The most likely cause of the error is that you tried
to use a complex value as a simple one. For example, you tried to use
a query variable in a cfif tag.
It occurs at line " cfloop index="local.thisRight" list="#rights#" ". It seems like ColdFusion does not like the "rights" here.
Anyone can give me some help? Thanks so much.
<cfif local.profile.rights.profile.self is not "">
<cfquery name="local.getAffiliations" datasource="#Request.readerDSN#">
SELECT tblPersonsToAffiliations.affiliationID, tblPersonsToAffiliations.rights, tblAffiliations.affiliationType, tblPersonsToAffiliations.relationshipType
FROM tblPersonsToAffiliations INNER JOIN tblAffiliations
ON tblPersonsToAffiliations.affiliationID = tblAffiliations.affiliationID
WHERE tblPersonsToAffiliations.personID IN (#local.profile.rights.profile.self#)
AND (tblPersonsToAffiliations.archived IS NULL
OR tblPersonsToAffiliations.archived = '')
</cfquery>
<cfif local.getAffiliations.recordCount is not 0>
<cfloop query="local.getAffiliations">
<cfif local.getAffiliations.relationshipType is "interested">
<cfset local.thisRelationshipType = "provisionalMember">
<cfif IsDefined("local.profile.rights.#affiliationType#.#local.thisRelationshipType#")>
<cfset local.profile.rights[affiliationType][local.thisRelationshipType] = ListAppend(local.profile.rights[affiliationType][local.thisRelationshipType], affiliationID)>
<cfelse>
<cfset local.profile.rights[affiliationType][thisRelationshipType] = affiliationID>
</cfif>
<cfelse>
<cfset local.thisRelationshipType = "fullMember">
<cfif IsDefined("local.profile.rights.#affiliationType#.#local.thisRelationshipType#")>
<cfset local.profile.rights[affiliationType][local.thisRelationshipType] = ListAppend(local.profile.rights[affiliationType][local.thisRelationshipType], affiliationID)>
<cfelse>
<cfset local.profile.rights[affiliationType][local.thisRelationshipType] = affiliationID>
</cfif>
<cfif isNull(rights)>
<cfelse>
<cfloop index="local.thisRight" list="#rights#" >
<cfif IsDefined("local.profile.rights.#affiliationType#.#local.thisRight#")>
<cfset local.profile.rights[affiliationType][local.thisRight] = ListAppend(local.profile.rights[affiliationType][local.thisRight], affiliationID)>
<cfelse>
<cfset local.profile.rights[affiliationType][local.thisRight] = affiliationID>
</cfif>
</cfloop>
</cfif>
</cfif>
</cfloop>
</cfif>
</cfif>
A bit earlier in your code you do this:
<cfif local.getAffiliations.relationshipType is "interested">
I think you need the same query name prefix in front of "rights" that is used when evaluating "relationshipType".
Try this:
#local.getAffiliations.rights#
HTH!
I am betting it is failing on this line:
<cfloop index="local.thisRight" list="rights" >
You are attempting to use the string "rights" as a list. My first reaction would be that you need to make that:
<cfloop index="local.thisRight" list="#rights#" >

ColdFusion isDefined

I am trying to check to see if data exist in my form If data does not exist I want to assign it to O. How can I do this.
<cfif not isDefined("FORM.Age")>
cfset FORM.Age = "0"
<cfif>
Generally the best practice is considered to be to avoid isDefined. This is because isDefined will search all scopes until it finds a matching variable. So it's more efficient to use structKeyExists, eg:
<cfif NOT structKeyExists(form, "age")>
<cfset form.age = 0>
</cfif>
Also, another way to achieve this is to use cfparam, and specify 0 as the default:
<cfparam name="form.age" default="0">
You're almost there:
<cfif not isDefined("FORM.Age")>
<cfset Form.Age = 0>
</cfif>
Technically what you have is fine once you enclose the cfset in tags < and >. Assuming that omission is just a typo, could it be you are trying to use it with a text field?
Text fields always exist on submission. The value may be an empty string, but the field itself still exists, so IsDefined will always return true. If that is the case, you need to examine the field length or value instead. Then do something if it is empty according to your criteria. For example:
<!--- value is an empty string --->
<cfif NOT len(FORM.age)>
do something
</cfif>
... OR
<!--- value is an empty string or white space only --->
<cfif NOT len(trim(FORM.age))>
do something
</cfif>
... OR
<!--- convert non-numeric values to zero (0) --->
<cfset FORM.Age = val(FORM.Age)>
There are actually two things you want to to ensure. First, make sure this page was arrived at by submitting the proper form. Next, ensure you have a numeric value for the form.age variable. Here is an example of how you might want to code this:
<cfif StructKeyExists(form, "age") and cgi.http_referrer is what it should be>
<cfif IsNumeric(form.age) and form.age gt 0>
<cfset AgeSubmitted = int(form.age)>
<cfelse>
<cfset AgeSubmitted = 0>
</cfif>
...more code to process form
<cfelse>
...code for when page was not arrived at properly
</cfif>

How to check value in an Array using Coldfusion?

I have the below code:
<cfset abcList = "*,B,b,A,C,a">
<cfset abcList=ListToArray(abcList,',')>
When I output 'abcList' then it is giving me a value but when I use the 'abcList' in <cfif> it's not working. Here is the code which is creating the problem:
<cfoutput>
#abcList[1]# <!---This is giving '*' as Correct o/p--->
<cfif #abcList[1]# eq '*'> <!---Here its going in else--->
list has * at first place
<cfelse>
* is not first
</cfif>
</cfoutput>
Any suggestions on what's wrong in my code?
You don't necessarily need to convert the list to an array. If you are starting from a list variable, you may use Coldfusion list functions to do the same thing without specifying the array conversion.
<cfset abcList = "*,B,b,A,C,a">
<cfif Compare(listGetAt(abcList, 1), '*') EQ 0>
Match
<cfelse>
No Match
</cfif>
Note that most of Coldfusion's string comparisons are not case sensitive. So if you need to test that 'B' is not the same as 'b', you will need to use the compare() function or else use one of the Regular Expression string functions. In this case, compare() returns 0 if string 1 equals string 2. If you do not need case sensitivity, then you may simplify further:
<cfset abcList = "*,B,b,A,C,a">
<cfif listGetAt(abcList, 1) EQ '*'>
Match
<cfelse>
No Match
</cfif>
It also works fine for me. Perhaps you have some extra spaces in the list values? That would skew the results:
<cfset abcList = "#chr(32)#*,B,b,A,C,a">
<cfset abcList=ListToArray(abcList,',')>
<cfoutput>
The value of abcList[1] = #abcList[1]# <br/>
<cfif abcList[1] eq '*'>
list has * at first place
<cfelse>
The else condition was hit because abcList[1] is "(space)*" and not just "*"
</cfif>
</cfoutput>
Try trimming the value first. Also, the # signs around the value are not needed.
<cfif trim(abcList[1]) eq '*'>
....
</cfif>
If that does not work, display the ascii values of both characters. Perhaps they are different than you are thinking.
<cfoutput>
ASCII abcList[1] = #asc(abcList[1])# <br/>
ASCII "*" = #asc("*")# <br/>
</cfoutput>
<cfset abcList = "*,B,b,A,C,a">
<cfset abc=ListToArray(abcList)>
<cfif #abc[1]# eq "*">OK<cfelse>FAIL</cfif>
<cfif abc[1] eq "*">OK<cfelse>FAIL</cfif>
Prints "OK OK" for me. Can you re-confirm it prints something else for you?