Sorry about the question phrase. I couldn't find better way to describe it. But my problem is as follows:
I have 3 cfc's namely settings.cfc, prices.cfc and helpers.cfc. These cfc's extend 4th cfc controller.cfc.
The helper.cfc is as follows:
<cfcomponent extends="Controller">
<cffunction name="formatCurrency">
<cfset formattedCurrency = 1 />
<cfreturn formattedCurrency>
</cffunction>
<cffunction name="processTemplateVariables">
<cfargument name="templateText" default="defaultText" >
<cfset formatCurrency() />
<cfreturn formattedCurrency >
</cffunction>
</cfcomponent>
The settings.cfc has a setApplicationVariables method which we use to set the application level variables. In this cfc, i have created an object of helpers.cfc and put that object into the application scope. The settings.cfc is as follows:
<cfcomponent extends="Controller">
<cffunction name="setApplicationVariables">
<cfset application.helpers = createObject("component","controllers.Helpers") />
</cffunction>
</cfcomponent>
The settings.cfc gets invoked on application start which in turn creates a object of helpers.cfc and put it into the application scope.
We create a reference to the method ProcessTemplateVariables in the controller.cfc as follows:
<cfcomponent extends="Wheels">
<cfset getFormattedCurrency = application.helpers.processTemplateVariables >
</cfcomponent>
In the prices.cfc, we use this reference to call the function processTemplateVariables
, which it does. But it does not call the function formatCurrency
that is called inside from the processTemplateVariables and it throws error "variable formatCurrency is undefined".
But if i use the application.helpers.processTemplateVariables(templateText="someText")
, it works.
It also works, when i use cfinvoke as bellow:
<cfinvoke method="processTemplateVariables" component="controllers.helpers" templateText="someText" returnvariable="content">
The prices.cfc is as follows:
<cfcomponent extends="Controller">
<cffunction name="index">
<!--- does not work, throws 'the formatCurrency() variable is undefined' --->
<cfdump var="#getFormattedCurrency("someText")#"><cfabort>
<!--- works --->
<cfinvoke method="processTemplateVariables" component="controllers.helpers" templateText="someText" returnvariable="content">
<!--- works --->
<cfset application.helpers.processTemplateVariables("someText") />
</cffunction>
</cfcomponent>
I am not sure why using reference is not working. Sorry about the earlier confusion but your comments made me dig deeper and i could found out that it was reference that was culprit. Is there any way to make this work with reference, that would be cool?
Update:
This blog entry (by Adam Cameron) has a better description. To summarize:
In your specific case it does matter. The function has a dependency on
formatCurrency
, which does not exist in the "context" of the calling page, and that is why you get an "undefined" error.(From comments)
Yeah, I am pretty sure you cannot do that. Each function is compiled into an individual class: specifically a static inner class. (You can see the inner class names if you dump out the function name without parenthesis ie
#application.helpers.formatCurrency#
) In other words, it is disconnected from any specific instance - and by extension - the other functions.When you create an instance of the component, all of the functions are stored its
variables
scope. So when you invoke "processTemplateVariables" - from within the instance - it has access to the other functions via the component'svariables
scope. When your code creates a reference to that function, what you are actually getting is completely disconnected from the parent instance ieapplication.helpers
. So it won't have access to any of the other functions. Hence why you get an "undefined" error.