Question

I am trying to convert an application I support from application.cfm to application.cfc. I followed Ben Nadel's ColdFusion Application.cfc Tutorial And Application.cfc Reference, but my pages cannot access any of the variables in the APPLICATION scope, without adding APPLICATION. to the variable. As a side note, this application uses 0 cfc's currently.

here is my application.cfc.

<cfcomponent displayname="Application" hint="Handle the application" output="true">

    <cfset THIS.Name = "AAS" />
    <cfset THIS.ApplicationTimeout = CreateTimeSpan( 0, 60, 0 , 0) />
    <cfset THIS.SessionManagement = true />
    <cfset THIS.setClientCookies = false />
    <cfset THIS.versionNum = '1'>
    <cfset THIS.genericUserID = 'o005265'>
    <cfset THIS.genericPassword = 'zo005265'>

    <cffunction 
        name="OnApplicationStart" 
        hint="Fires when the application is first created." 
        access="public" 
        output="false" 
        returntype="boolean">

       <cfset APPLICATION.aasURL = 'http://127.0.0.1:8500/aaas'>
       <cfset APPLICATION.dsn = 've0_aaas'>
       <cfset APPLICATION.aas_system = 'development (studio)'>

    <cfreturn true />
  </cffunction>
</cfcomponent>

Basically I just copied what was in the application.cfm page, and figured it would work the same. I am guessing that I have to invoke this somewhere? That is the only thing that I can think of. Any help would be great.

--- EDIT ---

I have added the OnRequest and OnApplicationStart methods after @EvikJames answer

<cffunction name="OnApplicationStart" access="public" returntype="boolean" output="false" hint="Fires when the application is first created.">
    <!--- Return out. --->
    <cfset APPLICATION.aasURL = 'http://127.0.0.1:8500/aaas'>
    <cfset APPLICATION.datasource = 've0_aaas'>
    <cfset APPLICATION.aas_system = 'development (studio)'>
    <cfreturn true />
</cffunction>


<cffunction name="OnRequest" access="public" returntype="void" output="true" hint="Fires after pre page processing is complete.">
    <!--- Define arguments. --->
    <cfargument name="TargetPage" type="string" required="true">
    <!--- Include the requested page. --->
    <cfinclude template="#ARGUMENTS.TargetPage#" />

    <cfset VARIABLES.dsn = APPLICATION.dsn>
    <cfset VARIABLES.aasURL = APPLICATION.aasURL>
    <cfset VARIABLES.aas_system = APPLICATION.aas_system>
    <!--- Return out. --->
    <cfreturn />
</cffunction>
Was it helpful?

Solution

In your onApplication start method, do this:

<cfset APPLICATION.datasource = 'MyDSN'>

In your onRequest method, do this:

<cfset VARIABLES.DSN = APPLICATION.datasource>

Then, this query will work:

<cfquery datasource="#dsn#">
// sql
</cfquery>

I should add that when you are fully upgraded, you can remove all of the code above just set the default datasource:

<cfset THIS.datasource = 'MyDSN'>

OTHER TIPS

You aren't really trying to use "application" variables (which always need to be scoped). I suspect your old application.cfm page had something like.

<cfapplicatin name="blah"...>

<cfset dsn = 'mydsn'/>

And then you were able to do:

<cfquery datasource="#dsn#">

This approach does not utilze the application scope ... it is merely taking advantage of the fact that your application.cfm always runs no matter what. What it is actually doing is putting variables in the variables scope. Because CF always checks the "variables" scope first you soemthing like #dsn# works - but that is not the same as the application scope.

To mimic this behavior in Application.cfc (as has been suggested) you will need to put your variable in the "onRequest()" function instead of the "onApplicationstart()" function - like so:

<cffunction name="onRequest">
<cfset dsn = 'mydsn'/>
</cffunction>

That is expected. To reference application variables you need to prefix them with application.

If the variable is in the application scope, you will always need to identify it that way in your .cfm pages. If you use a variable name without the scope prefix, the application scope is not looked at.

if you want to declare variables in the application.cfc that can be accessed without the application scope in your other pages, simply declare the variables outside of any functions.

<component>
   <cfset this.name = "applicationName">
   <cfset otherVar = 'something'>
   <cfset otherVar2 = 'something else'>

   <cffunction name="onApplicationStart>.....</cffunction>
</component>

otherVar and otherVar2 can be called without scope prefix on all .cfm pages.

It sounds like you were not originally using application scoped variables. If the variables were not originally scope with "application." then they were simply in "variables scope" (confusing wording I know) which is accessible by the cfm page hit and others included. That is one big change when moving between application.cfm and application.cfc. The general idea there follows the principle that included CFM files share variables scope and CFC files do not.

If the only change you have to make is changing #dsn# to #appplication.dsn# then just do it and get it over with. There are tools such as WinGrep or even Notepad++ which have find and replace across multiple files.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top