ColdFusion - Reference variables in cfloop using query generated from UDF

716 views Asked by At

I'm new to ColdFusion and have an interesting question regarding accessing variables inside a cfloop using a query that is generated from a query function.

I know I can create a variable, assign the result of the query function to the variable, and then loop over the variable containing the query result and access the data using the variable name given to the query attribute inside the loop as follows:

<cfscript>
    q = createObject("component", "cfc.myDBquery");
    result = q.myQuery();
</cfscript>    

<cfloop query="result">
    <cfoutput># result.MY_DATA #</cfoutput>
</cfloop>

However, consider this example:

<cfscript>
    q = createObject("component", "cfc.myDBquery");
</cfscript>

<cfloop query="#q.myQuery()#">
    <cfoutput># ???.MY_DATA #</cfoutput>
</cfloop>

Other than just outputting the data using the column name from the query (e.g. MY_DATA), how would I go about referencing this specific query when outputting data in the loop?

FWIW, Adobe shows this type of scenario in their documentation, however fails to show outputting data inside of the loop using this method:

https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-tags/tags-j-l/cfloop-looping-over-a-query.html

I know I'm being a bit neurotic for trying to eliminate one line from my code, I'm just curious if this is even possible while adhering to best practices.

2

There are 2 answers

2
CFMLBread On

I believe there are 2 possibilities. First, ColdFusion doesn't require the scope when looping over a query so you could just reference the field name you need from the query like so:

<cfloop query="#q.myQuery()#">
<cfoutput>#MY_DATA#</cfoutput>
</cfloop>

Knowing non-scoped variables cause confusion and anger, I believe you can reference the name of the original query from your function call. For instance, if your 'myQuery()' function is something like:

<cffunction name="myQuery">
<cfquery datasource="myDS" name="myQry">
    SELECT * FROM Names
</cfquery>
<cfreturn myQry>
</cffunction>

Then your can reference 'myQry' like so:

<cfloop query="#q.myQuery()#">
<cfoutput>#myQry.MY_DATA#</cfoutput>
</cfloop>
0
Dan Bracuk On

This is a long formatted comment. Here:

<cfscript>
    q = createObject("component", "cfc.myDBquery");
    result = q.myQuery();
</cfscript>  

Creating the object makes the myQuery() function available. It doesn't actually run it. You might be able to do this:

result = createObject("component", "cfc.myDBquery").myQuery();

Next, since you asked about best practices, don't do this:

<cfloop query="result">
    <cfoutput># result.MY_DATA #</cfoutput>
</cfloop>

You are executing the cfoutput tag each time through the loop. Instead, do this:

<cfoutput>
<cfloop query="result">
    #result.MY_DATA #
</cfloop>
</cfoutput>

or this

<cfoutput query="result">
#MY_DATA#
</cfoutput>

It behaves like a loop. Other comments about best practices are simply opinions. One of mine is that readable code is good code.