I am trying to access recipeIngredient in this array.
I have tried this:
<cfloop from="1" to="#ArrayLen(contents)#" index="i">
<cfoutput>
#i.recipeIngredient#<br>
</cfoutput>
</cfloop>
I am getting an error "You have attempted to dereference a scalar variable of type class coldfusion.runtime.Array as a structure with members."
CodePudding user response:
You are using nested data, so you need to check for the existance of that particular struct that has the key recipeIngredient
to output it.
In that case I wouldn't iterate the arrays by index, because CFML gives the wonderful possibilty to cfloop an array by using the attribute array and iterate it by its items, which feels more natural and easier to read.
Also, don't add <cfoutput>
to the inner body of loops, because it adds more overhead to your cfengine. Instead, embrace the loops with cfoutput.
<cfoutput>
<cfloop array="#contents#" item="item">
<cfif isStruct( item ) and structKeyExists( item, "recipeIngredient")>
<cfloop array="#item.recipeIngredient#" item="ingredient">
#ingredient#<br>
</cfloop>
</cfif>
<!--- for looping over a struct like recipeinstructions use collection attribute--->
<cfif isStruct( item ) and structKeyExists( item, "recipeinstructions")>
<cfloop collection="#item.recipeinstructions#" item="key">
Value for key '#encodeForHTML(key)#': #encodeForHTML( item.recipeinstructions[key])#<br>
</cfloop>
</cfif>
</cfloop>
</cfoutput>
CodePudding user response:
Another way of looping is to use an index
loop instead of an array
loop or a collection
loop and then loop from 1 to the arrayLen()
of the array. Either way is fine. I typically prefer this method as being easier to read when accessing deeper nested level structures and arrays. If you choose to use this, you can refactor your code as follows. if you would like to see, I created a working demo here.
<cfoutput>
<h4>Ingredients</h4>
<cfloop index="i" from="1" to="#arrayLen(contents['recipeIngredient'])#">
#contents['recipeIngredient'][i]# <br>
</cfloop>
<h4>Instructions</h4>
<cfloop index="i" from="1" to="#arrayLen(contents['recipeInstructions'])#">
#contents['recipeInstructions'][i]['@type']# <br>
#contents['recipeInstructions'][i]['name']# <br>
#contents['recipeInstructions'][i]['text']# <br>
#contents['recipeInstructions'][i]['url']# <br>
#contents['recipeInstructions'][i]['image']# <br>
<br>
</cfloop>
</cfoutput>