Dealing with WhiteSpaces while accessing Structure "keys" - coldfusion

Please consider the following image:
So, How do I correctly access "Android Phone" key in the structure. When I do the following(An excerpt from my code):
<cfloop from="1" to="#arraylen#" index="i">
<cfif structKeyExists(cfData[i], "open")>
<cfoutput>#cfData[i].open.AOL#</cfoutput>
<cfelse>
NULL
</cfif>
</cfloop>
It works fine, however, when I try to <cfoutput> it like the following :
<cfoutput>#cfData[i].open.Android Phone#</cfoutput>
OR
<cfoutput>#cfData[i].open.AndroidPhone#</cfoutput>
I get the following error:
Element OPEN.ANDROIDPHONE is undefined in a CFML structure referenced as part of an expression.
The error occurred in C:myfile.cfm: line 185
183 : <!--- <cfloop list="#KeyList#" index="colItem"> --->
184 : <cfif structKeyExists(cfData[i], "open")>
185 : <cfoutput>#cfData[i].open.AndroidPhone#</cfoutput>
186 :
187 : <cfelse>
Question #2: I am encountering one more weird phenomenon:
When I am outputtin the values like the following:
<cfoutput>#cfData[i]["open"]["Android Phone"]#</cfoutput>
and
<cfoutput>#cfData[i]["open"]["Android Tablet"]#</cfoutput>
It works perfectly fine.
However, when I change it to following:
<cfoutput>#cfData[i]["open"]["Lotus Notes"]#</cfoutput>
I am getting the following error:
Element Lotus Notes is undefined in a CFML structure referenced as part of an expression.
The error occurred in C:myfile.cfm: line 185
183 :
184 : <cfif structKeyExists(cfData[i], "open")>
185 : <cfoutput>#cfData[i]["open"]["Lotus Notes"]#</cfoutput>
186 :
187 : <cfelse>
Is it like it only works for a series of space related keys and not for the one which occur after single words keys? Please advise.

In this case because of the space you can't use the dot notation so you must use the bracket-quote notation:
<cfoutput>#cfData[i]["open"]["Android Phone"]#</cfoutput>

Related

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>

Checking the structure is existing or not

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>

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

ColdFusion ImageWrite to Amazon S3

This is a strange one - I have 'virtually' identical code on 2 pages, it works on one but not the other. The incredibly unhelpful error message, "S3 Error Message." doesn't shed any light on where I'm going wrong with this.
The code below is identical on both pages - the only (very slight) difference between the 2 pages is the way imgLink is generated - on the working page it is obtained from a single source (an XML feed) and cfset, on the none-working page imgLink is initially set as 'none' and then a number of sources are checked until it finds one - it's still cfset in the same way, and I have a cfif to make sure it's valid before processing. HOWEVER - I have also tried hardcoding the source (i.e., pasting in the value that would usually be in the imgLink cfset) and it still fails.
I've debugged this in every way I can possibly think in the last day, without success. So, I guess I'm looking for pointers as to what else I should look at that could be causing it to fail.
The full error returned is -
An error occurred when performing a file operation create on file s3://mybucket/1577-67BC4EF7-1B21-866F-32E95DF67F3336C6-f.jpg.
The cause of this exception was: org.apache.commons.vfs.FileSystemException: Unknown message with code "S3 Error Message."..
And my code is;
<cfscript>
this.name ="Object Operations";
this.s3.accessKeyId = "accessKey";
this.s3.awsSecretKey = "secretKey";
this.s3.defaultLocation="EU";
</cfscript>
<!--- CFImage Stuff --->
<!--- S3 Permissions --->
<cfset perms = [{group="all", permission="read"}]>
<!--- Create the Images ---->
<cfset imageuuid = '#CreateUUID()#'>
<cfset imagefull = '#getid.id#-#imageuuid#-f.jpg'>
<cfset imagemain = '#getid.id#-#imageuuid#-m.jpg'>
<cfset imagethumb = '#getid.id#-#imageuuid#-t.jpg'>
<cfimage action="read" name="img1" source="#imgLink#">
<!--- Create the full size image 505 x N --->
<cfif img1.height GT img1.width>
<cfif img1.width GTE 505>
<cfset ImageResize(img1,'505','')>
</cfif>
<cfelseif img1.width GT img1.height>
<cfif img1.width GTE 505>
<cfset ImageResize(img1, '505','')>
</cfif>
</cfif>
<cfset ImageWrite(img1, "s3://mybucket/#imagefull#")>
<cfset StoreSetACL("s3://mybucket/#imagefull#","#perms#")>
<!--- Create the main size image 251 x N --->
<cfif img1.height GT img1.width>
<cfif img1.width GTE 251>
<cfset ImageResize(img1,'251','')>
</cfif>
<cfelseif img1.width GT img1.height>
<cfif img1.width GTE 251>
<cfset ImageResize(img1, '251','')>
</cfif>
</cfif>
<cfset ImageWrite(img1, "s3://mybucket/#imagemain#")>
<cfset StoreSetACL("s3://mybucket/#imagemain#","#perms#")>
<!--- Create the thumbnail 52 x 52 --->
<!--- resize image to 52 pixels tall if width is greater then height --->
<cfif img1.height GT img1.width>
<cfset ImageResize(img1,'52','')>
<cfset fromX = img1.Height / 2 - 26>
<cfset ImageCrop(img1,0,fromX,52,52)>
<!--- resize image to 75 pixels wide if height is greater then width --->
<cfelseif img1.width GT img1.height>
<cfset ImageResize(img1,'','52')>
<cfset fromY = img1.Width / 2 - 26>
<cfset ImageCrop(img1,fromY,0,52,52)>
<cfelse>
<cfset ImageResize(img1,'','52')>
<cfset ImageCrop(img1,0,0,52,52)>
</cfif>
<cfset ImageWrite(img1, "s3://mybucket/#imagethumb#")>
<cfset StoreSetACL("s3://mybucket/#imagethumb#","#perms#")>
Just realised I hadn't added my solution to this, so here it is- The folder in which the 'non-working' code was in had it's own Application.cfc, which didn't include the S3 elements in the code posted above. The 'working' code did have that in the corresponding Application.cfc.
Not quite sure why that had to be in Application.cfc when it was at the
The this object in application.cfc is an application component and this on ColdFusion page is just a structure variable. Put <cfdump var=#this#> in both places, application.cfc and yourfile.cfm, to see the difference.