Element undefined error when looping an Array with an empty value
Hoping someone can give me an idea of what I'm doing wrong.
I'm looping over an array and outputting the values....simply enough. However if a field is empty I get an Element <VARIABLE> is undefined in <INDEX>
.
E.g.
<cfloop array="#allocationDetails.offerings#" index="myIndex">
#myIndex.name#
#myIndex.number#
#myIndex.somefield#
</cfloop>
This works fine until a field has no value. E.g myIndex.somefield is empty then I get the error:
"Element somefield is undefined in myIndex"
If I wrap the field output in checks like isDefined("myIndex.somefield") or structKeyExists(myIndex,"somefield") etc, they return true but then I get the error "Element somefield is undefined in myIndex" when I try to output the field value.
I also tried cfdump on the myIndex.somefield and get the same error.
I would have thought this was a pretty basic thing to do but I can't see why this is getti开发者_Python百科ng an error. Am I missing something really obvious?
Thanks for your help.
Cheers Mark
Maybe there is no array element for that index? For example:
<cfscript>
myArr = ArrayNew(1);
myArr[1] = 'xx';
myArr[2] = 'yy';
myArr[4] = 'zz';
</cfscript>
If you try looping through it you could add a ArrayIsDefined check:
<cfloop array="#myArr#" index="myIndex">
<cfif ArrayIsDefined(myArr, myIndex)>
#myIndex#
</cfif>
</cfloop>
If not, then there's always try catch:
<cfloop array="#myArr#" index="myIndex">
<cftry>
#myIndex#
<cfcatch type="any">
Error or default variable setting here
</cfcatch>
</cftry>
</cfloop>
This is totally untested, but have you tried something like this?
<cfloop array="#allocationDetails.offerings#" index="myIndex">
<cfparam name="myIndex.name" default="" />
<cfparam name="myIndex.number" default="" />
<cfparam name="myIndex.somefield" default="" />
#myIndex.name#
#myIndex.number#
#myIndex.somefield#
</cfloop>
If you're using ColdFusion 9, the error you're getting is due to undefined, or NULL values being returned from the webservice call. Try this instead:
<cfif StructKeyExists(myIndex, "somefield") AND NOT IsNull(myIndex.somefield)>
#myIndex.somefield#
</cfif>
Dump the #allocationDetails.offerings# and see the output.
You are basically looping over the array. So you will be able to see the outcome of each index value.
Also, May be idiotic but sometimes it works. Assign the allocationDetails.offerings to a variable and then loop that variable.
<cfset some_var = allocationDetails.offerings />
<cfloop array="#some_var#" index="indexNow">
.
.
</cfloop>
Finally, Also change the variable of index from myIndex to some other name.
<cfscript>
allocationDetails.offerings = ArrayNew(1);
allocationDetails.offerings[1] = {name = 'a', number = 1 , somefield = "somevalue"};
allocationDetails.offerings[2] = {name = 'a', number = 2 , somefield = "somevalue"};
allocationDetails.offerings[4] = {name = 'c', number = 3 , somefield = "somevalue"};
</cfscript>
<cfoutput>
<cfloop array="#allocationDetails.offerings#" index="myIndex">
<cfparam name="myIndex.name" default="" />
<cfparam name="myIndex.number" default="" />
<cfparam name="myIndex.somefield" default="" />
#myIndex.name# : #myIndex.number# : #myIndex.somefield#<br>
</cfloop>
</cfoutput>
Steve solution will work fine.
Wow this really has me confused.
In the loop (of my real code looping the web service arrays) if I use something like:
#StructKeyList(myIndex)#
It spits out a list of available keys in myIndex, which includes ALL the field names as expected, including the fields that exist but are empty.
So doing checks like StructKeyExists(myIndex, “somefield”) or isDefined(“myIndex.somefield”) are returning true because the key does exist. But if I then try to output the field myIndex.somefield I get the Element somefield is undefined in myIndex error. I don’t understand why this is a problem. I’ve also tried using but that doesn’t seem to be doing anything (to my arrays).
If I try all the previous steps on the example array and loops it works as expected. It’s just when I try the above to the results of the web service that I’m having problems.
Has anyone seen this issue when dealing with web service recordsets (on CF8)?
Now onto work arounds….one suggestion that works (thanks Leigh) is rather than using myIndex.somefield is to call the getSomeField method in the web service and use its result instead (which works even if the value is empty).
The other thing that I just tried that is also (for whatever reason) working is dropping the index name from isDefined, so instead of:
isDefined(“myIndex.somefield”)
I use:
isDefined(“somefield”)
Again this does appear to be a CF8 related problem because if I run the code on CF9 using StructKeyExists, IsDefined, or IsNull they all work as expected.
I was doing something similar. I wanted the average value from an array that could have undefined values. I finally came up with two different ways to do this.
<cffunction name="ArrayAvg2">
<cfargument name="theArray" required="true">
<cfset sum=0>
<blockquote>
<cfloop from=1 to="#ArrayLen(theArray)#" index="i">
<cfif ArrayIsDefined(theArray, i)>
<cfoutput>theArray[#i#] = #theArray[i]#</cfoutput>
<cfset sum += theArray[i]>
<cfelse>
Undefined
</cfif>
<br/>
</cfloop>
</blockquote>
<cfreturn sum>
</cffunction>
<cffunction name="ArrayAvg3">
<cfargument name="theArray" required="true">
<cfset sum=0>
<blockquote>
<cfloop from=1 to="#ArrayLen(theArray)#" index="arrayElement">
<cfif ArrayIsDefined(theArray, arrayElement)>
<cfoutput>theArray[#arrayElement#] = #theArray[arrayElement]#</cfoutput>
<cfset sum += theArray[arrayElement]>
<cfelse>
Undefined
</cfif>
<br/>
</cfloop>
</blockquote>
<cfreturn sum>
</cffunction>
<cfset testArray=ArrayNew(1)>
<!--- no testArray[2] --->
<cfset testArray[1]=10>
<cfset testArray[3]=30>
testArray = <cfdump var="#testArray#">
<br/>
ArrayAvg2 = <cfdump var="#ArrayAvg2(testArray)#">
<br/>
ArrayAvg3 = <cfdump var="#ArrayAvg3(testArray)#">
I hope this helps.
(BTW, I'm a noobie with ColdFusion, so if you see anything I'm doing wrong let me know!)
精彩评论