Checking the structure is existing or not - coldfusion

Here is my array loop which has structures inside that
I am looping over it and i need to skip those fields where the struct is not defined, howver i am getting everytime
Here is my code:
<cfloop index="apos" from=1 to="#arrayLen(myarray)#">
<cfdump var="#myarray[apos].company#">
<cfdump var="#StructKeyExists(myarray[apos].company,'#myarray[apos].company.size#')#">
<cfdump var="#StructFindKey(myarray[apos].company,'myarray[apos].company.size','ALL')#">
</cfloop>
The error is throwing on line 3, where i am getting error: Element COMPANY.SIZE is undefined in a CFML structure referenced as part of an expression.
Although i had tried the structFindvalue, but that does not work, perhaps that is expecting some simple values, so what could be the best possible alternative here

With structKeyExists you want to give that function the struture to look and the key you're looking for, so in myarray[apos].company you want to see if 'size' exists, not the entire structure.
<cfloop index="apos" from=1 to="#arrayLen(myarray)#">
<cfdump var="#myarray[apos].company#">
<cfdump var="#StructKeyExists(myarray[apos].company,'size')#">
</cfloop>

Related

CFSET Invoking Function without variable

New pretty new with this language, started code with it this week.
So my problem is the new company that I started with uses CF11 and they mainly only code with tags. I want to know if is possible to call cfset without a variable declaration.
If not what is the better way to call functions (that don't have return) with tags?
<cfset myFunction()>
I usually call my initiate functions at cfset, but they all have returning.
<cfset something = #initSomething()#>
Yes, invoking a function without capturing the result is perfectly fine. Sadly, there used to be a lot of that syntax in older CF documentation. It gave the erroneous impression you MUST capture the result of a function (and use extra pound signs everywhere). Neither is true. Even if a function does return something, you're not required to capture the result. Only if you wish to use it for something later. You're always free to invoke a function and completely ignore the result. So both of these are valid:
<!--- 1. capture result --->
<cfset result = getTimeNow()>
<!--- 2. ignore result --->
<cfset getTimeNow()>
<!--- sample function --->
<cffunction name="getTimeNow" return="date">
<cfreturn now()>
</cffunction>
Technically, there's nothing stopping you from capturing the result of a function that doesn't return anything. However, the "result" variable will be undefined, so it really serves no purpose.
<cfset result = doNothing()>
<!--- this will error --->
<cfoutput>#result#</cfoutput>
<!--- sample function --->
<cffunction name="doNothing" return="void">
<!--- function that returns nothing --->
</cffunction>

Output list in cfloop with two variables

I have following code:
<cfloop from="1" to="3" index="i">
<cfloop list="#FORM.cboStructureLevel_#i##" index="ii" delimiters=",">
#ii#
</cfloop>
</cfloop>
The problem is that I want to output the list but I am getting the error "Element CBOSTRUCTURELEVEL_ is undefined in FORM.". It does not recognize the output of #i# in the list in the second cfloop.
How can I output the whole list as declared above?
Thank you for your help.
Try this for your inner loop:
<cfloop list="#form['cboStructureLevel_' & i]#" index="ii">
try to use evaluate function:
#Evaluate('FORM.cboStructureLevel_#i#')#

cfdirectory loop limit the results

I' am finding it difficult to understand this. How can I limit the results to 50 only. Let say if in the directory I have 1000 files, how can I limit it so that only 50 files are looped over.
<cfdirectory action="list" directory="#ExpandPath('/downloaded/')#" name="listRoot" filter="*.xml" recurse="false" sort="datelastmodified asc">
<cfoutput>
<cfloop query="listRoot" from="1" to="50" index="i">
....
</cfloop>
</cfoutput>
When I run the above code I get the following error message
Attribute validation error for tag CFLOOP.
If you review the complete error message, it contains the answer (emphasis mine):
It has an invalid attribute combination: from,index,query,to. Possible combinations are:
Required attributes: 'query'. Optional attributes: 'endrow,startrow'.
...
Required attributes: 'from,index,to'. Optional attributes: 'step'.
The code is attempting to mix two different types of loops: query loop and from/to loop. That is not a valid combination. You can either use a query loop OR a from/to loop, but not both.
Having said that, since the goal is to display the output, there is really no need for the cfloop. Just use cfoutput with the "startRow" and "maxRows" attributes:
<cfoutput query="listRoot" startRow="1" maxRows="50">
#name#<br>
</cfoutput>
As mentioned in the other answer, recent versions of CF also support for ...in loops:
<cfscript>
for (row in listRoot) {
writeOutput("<br>Debug: name value = "& row.name );
}
</cfscript>
You can access specific rows in a query with:
query[columnName][rowIndex]
In order to do a from to loop instead of an each loop, go:
<cfoutput>
<cfloop from="1" to="50" index="i">
#listRoot["name"][i]#<br>
</cfloop>
</cfoutput>

Is there any limitation with number queries/statements we can write inside cftransaction?

Today while fixing bugs in some existing code I found a strange error.
Branch target offset too large for short
After searching I found that it is something to do with Java byte code conversion. Here are the links I found:
Branch target offset too large for short
Branch Target Offset Error
Why does a long cfc file work in CF8, but not CF9? Getting "Branch target offset too large for short" error
In my case cftransaction contains around 870 statements and it's working fine. But I need to add 2 more queries to this transaction. Now I am getting this error when I am adding even one line of code inside cftransaction. Currently I can not move any of the existing cfquery out of the cftransaction.
Here is the overall structure of the code:
<cftransaction action="begin">
<cfif URL.action eq 'add'>
Around 200 lines of queries/statements
<cfelseif URL.action eq 'edit'>
Around 200 lines of queries/statements
</cfif>
<cfif URL.action eq 'add' or URL.action 'edit'>
Around 450 lines of queries/statements
</cfif>
</cftransaction>
Is there any workaround to fix this problem?
Branch offset has to do with the size of the module/function. It can also be caused due to a large conditional code block of cfif/cfelse or cfswitch.
Technically, I am not sure if there is any cap on the no. of queries you can put inside the cftransaciton block. It has nothing to do with the code migration from CF8 to CF9 but the length of your code inside conditional blocks.
I would want to split the function and try to put the each of the big sized conditional blocks as a separate function inside the cfc:
<cffunction name="myFunc1">
<cftransaction action="begin">
<cfif URL.action eq 'add'>
<!--- function call with your xxx lines of queries/statements --->
<cfinvoke component="MyCfc" method="firstQueryBlock" result="result1">
<cfelseif URL.action eq 'edit'>
<!--- second function call with your yyy lines of queries/statements --->
<cfinvoke component="MyCfc" method="secondQueryBlock" result="result2">
</cfif>
<cfif URL.action eq 'add' or URL.action 'edit'>
<!--- third function call with your zzz lines of queries/statements --->
<cfinvoke component="MyCfc" method="thirdQueryBlock" result="result3">
</cfif>
</cftransaction>
</cffunction>

Find value in a array of Structure

I am trying to find the value of a Struture which is contained inside an Array. The following diagram shows the representation:
I tried the code below, but it is giving me this error, using CF 9.0.1
Element OPTIONTYPE_NAME is undefined in a CFML structure referenced as part of an expression.
Code I am trying:
<cfif !ArrayIsEmpty(result)>
<cfset arrayIndex = 0>
<cfloop from="1" to="#ArrayLen(result)#" index="counter">
<cfif result[counter].OPTIONTYPE_NAME IS "color">
<cfset arrayIndex = counter>
<cfdump var="#arrayIndex#">
</cfif>
</cfloop>
Well the error is pretty much telling you what the problem is. There isn't a key OPTIONTYPE_NAME in result[counter].
result[counter] has keys key, owner and path.
I think you want to be looking at result[counter].owner.OPTIONTYPE_NAME