Application.cfc Scoped Functions Are Stored In Page VARIABLES Scope

Posted November 6, 2006 at 2:31 PM by Ben Nadel

Tags: ColdFusion

Holy cow! I just realized that Application.cfc-scoped methods such as OnApplicationStart() and OnRequestStart() as well as any other custom user-defined ColdFusion functions (in the Application.cfc) are stored in and are accessible via the current page's VARIABLES scope. Meaning, you can call things like:

  • <!--- Call application event. --->
  • <cfset VARIABLES.OnApplicationStart() />
  •  
  • <!--- Call UDF. --->
  • <cfset VARIABLES.UDFDefinedInAppCFC() />

This seems a bit silly to me, but I am glad I'm finally aware of this.




Reader Comments

Nov 6, 2006 at 3:57 PM // reply »
1 Comments

That's great to know! I have a couple of extra functions in my App.cfc that I use for logout/login and other stuff. I was bummed I couldn't access that same code from other templates. Sweet find!


Nov 6, 2006 at 10:49 PM // reply »
92 Comments

Yes that is the case with application.cfc. You can set up your own UDF's in the application.cfc and you can call them from any of your pages of course as long as the function is set to public. I've seen some people include it in the onRequestStart() (I think that was the one) but then they have to put it in the request scope just to access it. If you ask me its just much easier to drop in to application.cfc.


Nov 6, 2006 at 11:15 PM // reply »
4 Comments

I believe this is true only if you have the onRequest method in your app.cfc. I try not to use onRequest anymore because it interferes with web service CFCs and AJAX calls. But if this isn't an issue, it definitely is a cool by-product. I actually learned this from Ray Camden - see the comments for this post: http://ray.camdenfamily.com/index.cfm/2006/9/20/Using-JavaScript-to-warn-a-user-about-a-session-timeout.
Keep up your exploration!


Nov 7, 2006 at 8:25 AM // reply »
11,247 Comments

Rob,

Yeah, I hear you on the AJAX and CFC issues and OnRequest(). Ray Camden came up with a good solution for that by basically deleting the OnRequest() method whenever a CFC is called directly (or some sort of flash remoting, but I don't remember that one).


Jul 24, 2008 at 10:08 AM // reply »
2 Comments

What's the best way to make these UDF's defined in the app.cfc available to the code run in custom tags?


Jul 24, 2008 at 11:48 AM // reply »
11,247 Comments

@Lems,

I am not sure why you want to do that, but I suppose you could store a reference to the Application.cfc in the REQUEST scope. In your OnRequestStart() method, you could have something like:

<cfset REQUEST.Application = THIS />

Then, in your custom tags you could something like:

<cfset REQUEST.Application.OnRequestEnd() />

Not sure why, but I suppose that would work.


Jul 24, 2008 at 12:18 PM // reply »
2 Comments

Maybe I didn't explain it well, but regardless, I found this article to answer my question:

http://www.coldfusionjedi.com/index.cfm/2008/2/7/Ask-a-Jedi-Custom-Tags-OnRequestStart-UDFs-and-Antimatter-Engines

Thanks for the quick reply!


Jul 24, 2008 at 12:24 PM // reply »
11,247 Comments

@Lems,

Ok cool. Good luck.


Mar 16, 2009 at 4:06 PM // reply »
19 Comments

I have been converting my CMS arch to use app cfc from cfm the last little while and all this talk about onRequestStart/ajax interference freaked me out. I have discovered, and if you think about it, it is logical, onRequestStart has NO inherent interference with AJAX calls. The problem is with this 'template' of an application.cfc that certain circles are using where you try to cfinclude the requested cfm/cfc page/call. If you are not doing that, you need no special handling, no special logic to handle a direct remote cfc/ajax call. It works FINE. I feel MUCH better about converting to app cfc now and this also have reconfirmed my faith in the Adobe programmers whom I had a hard time believing would create an onRequestMethod that wouldn't allow cfc/ajax calls natively! I commented my results on Ray's blog after it was suggested it might be the actual onRequestStart causing the issue. Of course this brings into question the use of a template that requires special handling to re-fix something that wasn't broken. But if it works for you and you like it that way, cool cool. I'll continue to let my index.cfm handle the content driver cfc and the onRequest will just handle security cfc call and other aspect oriented programming calls with no special logic needed to handle cfc/cfm differentiation or manual invokes. There is no bug or issue, the onRequestStart works CORRECTLY and as expected. Much to my relief!


Mar 16, 2009 at 4:10 PM // reply »
19 Comments

And thanks, Ben, for discovering the way to call app cfc functions outside of itself! I was having a hard time guessing where they ended up and I couldn't get the app cfc to instantiate like other cfc's which was very strange indeed! That is what I was actually looking for!


Mar 17, 2009 at 8:36 AM // reply »
11,247 Comments

@William,

It is the OnRequest() method that causes some CFC-based call problems, not OnRequestStart() - in case there was any confusion. Having the OnRequestStart() should never cause any problems.


Mar 17, 2009 at 1:30 PM // reply »
19 Comments

Ah, that makes more sense. And makes me feel better. I must have sadly missed this distinction on this and Ray's blog. This thread was tackling both (for different reasons). I just read the Adobe docs on the onRequest() and it does explicitly state it is an interrupter for the page content and the page called (index.cfm, hoho.cfm, or myAjax.cfc) needs to be explicitly handled by the programmer. So the workarounds are effectively doing what the docs tell you that you have to. So this isn't as crazy as I thought it was, but it does appear Adobe has correctly warned us about this method. My AOP/Security pre-request (it used to be in application.cfm before the target page/cfc would get called, effectively onRequestStart() ) handles all the security, redirection and special cases already so it won't change for me. I won't need to use the onRequest method and will let a request make its natural call if it gets by onRequestStart().
Thanks for setting me straight!
-w


Mar 17, 2009 at 1:47 PM // reply »
11,247 Comments

@William,

No problem my man. I like to use OnRequest() to force people to include index.cfm no matter what is requested; but, for the most part, unless you are changing the template that gets requested, there is no real need for the OnRequest() method (and, as you see, it can cause problems).


Mar 17, 2009 at 1:49 PM // reply »
11,247 Comments

@William,

Also, take a look at this for a conversation on deleting the OnRequest() method programmatically based on the type of page request:

http://www.bennadel.com/index.cfm?dax=blog:1252.view


Apr 3, 2009 at 7:10 PM // reply »
19 Comments

hum... i may be back to where i started in a way on my original reason i read through this thread (not onRequest related).

i am trying to call application.cfc methods directly from another cfc that is invoked by the application cfc methods.

in short, on app initialization (onApplicationStart), i am creating some low level objects that don't have access to a more general error handler (because it is not created yet and depends on the low level stuff) and if these fail, i'd like to have them call onError (which basically does a more crude dump/basic email/txt msg of the error passed in so admins will be notified post haste.

so although variables.onError seems to work for a PAGE, it does not seem to be working inside a cfc.... i can extend application into the cfc and that works, but not as elegant as i wanted esp if there end up being lots of cfc's that need onError or other cfc's in the application.cfc. (prob not, just thinking ahead).

i guess i can create a cfc that extends and then inject the methods into the application core object methods so it is included in the constructors that pull in my core methods... just seems like if you can get to variables from a cfm, there should be a way to grab it from inside a cfc... guess that keeps the variables scopes protected from each other so it makes sense, but.... still.... any ideas? i guess i can also (re)throw (chain the catches) and push the stuff up which would then hit onError.. a bit cumbersome but that would work too...

maybe extending is the simplest solution afterall.


Apr 6, 2009 at 7:03 PM // reply »
19 Comments

Here is an oddity (to me) i couldn't see much/anything written about. Not really explained in cf docs, the arg is referenced, but not the behaviour. Maybe others have discovered this too.

So after eschewing onRequest(), but continuing to use onRequestStart() for all things AOP (security mainly), i was adding some more tracing/dump/logging options and added some explicit arguments which subsequently throw the method. I thought, "What? I'm not passing any arguments in yet... "

I was overloading all the arguments up until then. What i discovered is the Application provides your first argument to this method just like onRequest(), (at least when it is naturally fired off, haven't tested explicit calls yet), and it is the targetpage value (index.cfm for example). Since I had no args before, it was forcing it into my next arg regardless and failing on type (TraceOn is a boolean, for instance). So although you can ignore the hard-wired argument and don't need to set the argument explicitly (you can run it with no cfarguments), you cannot use explicit arguments unless you also include the first one as the targetPage (doesn't really matter what you call it, but the first arg will always get the page requested value).


Apr 9, 2009 at 9:22 AM // reply »
11,247 Comments

@William,

I am not sure that I fully understand what you are saying. Are you basically saying that you add additional arguments parameters to OnRequest()? If so, yes, the first one will *always* be the target page requested by the user.


May 27, 2009 at 12:04 PM // reply »
19 Comments

yes, i was using argumentCollection to overload onRequestStart() with no defined arguments and handling them myself, but as soon as I used a named <cfargument>'s CF would always force the target page into my first argument. I did not expect this. But it elucidates why onRequest() is a problem as well as it does the same thing this way and forces you to process this low-level hardwired argument.


Jun 1, 2009 at 2:01 PM // reply »
11,247 Comments

@William,

Hmm, that's interesting that the behavior would change when you use named arguments vs. argumentCollection. I guess the ARGUMENTS scope is just trying to reconcile the method signature (what it's expecting) with what you send it.


Jul 26, 2009 at 11:46 PM // reply »
3 Comments

Ben, sorry to keep resurecting an old post. I'm don't consider myslef a CF noob, but I'm having a hell of a time figuring out why I'm getting "The [method name] method was not found.: Either there are no methods with the specified method name and argument types, or the testMeth method is overloaded with argument types that ColdFusion cannot decipher reliably."

In Application.cfc I've go the following...

<cffunction name="testMeth" output="false" access="public" returntype="string">
<cfreturn "testMeth output!">
</cffunction>

And on a test page, in the same directory, I'm callling...

<cfoutput>#variables.testMeth()#</cfoutput>

Yet I'm getting the above mentioned error. Worse, when I CFDUMP the variables structure, it shows no object or data. Empty. Ugh.

Is there something special I'm supposed to do in Application.cfc to get the methods into the variables scope? Any help? Many thanks!


Jul 27, 2009 at 12:00 AM // reply »
19 Comments

@Phil,

which event is creating/instantiating your object? are you recreating the cfc in onRequest so it runs on every call? this would probably work... but you are reinstantiating the cfc every request. if you put it in some of the other events it isn't as obvious; i've found referencing a function put in some of the app cfc events is problematic and i've had to explicitly instantiate a copy of the methods i wanted to use. just putting cfc code in some parts (some events) of the app cfc does not necessarily instantiate them and make them available to the whole application unless you explicitly (manually) do so.


Jul 27, 2009 at 12:36 AM // reply »
3 Comments

@William,

Thank you for the fast, kind reply. What I have is a pretty generic Application.cfc file with OnApplicationStart(), OnRequestStart(), and onError() methods only. That worked fine. But then I added the <cffunction> block (in my previous post) before the end of the </cfcomponent> end tag and the test method "testMeth()" and it simply isn't being recognized. Based on Ben's initial post above that "as any other custom user-defined ColdFusion functions in the Application.cfc" I trued the VARIABLES.testMeth() but it's giving me hassles.


Jul 27, 2009 at 8:26 AM // reply »
11,247 Comments

@Phil,

The problem is that unless you use the OnRequest() event to include the executed template, the given template does *not* have access to the Application.cfc instance. By using the OnRequest() event method, you are creating a mixin, which makes the executing page, essentially, part of the Application.cfc:

http://www.bennadel.com/blog/805-ColdFUsion-Application-cfc-OnRequest-Creates-A-Component-Mixin.htm


Jul 29, 2009 at 4:19 PM // reply »
3 Comments

I finally had a minute to try this and it worked. Thank for all the help.



Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 25, 2013 at 10:01 PM
My Experience With AngularJS - The Super-heroic JavaScript MVW Framework
@Avi, Really glad to help! @Jaredwilli, I'm finding a this image hits home with a lot of people :) Hopefully we can all work through the rough patches together! @Prateek, AngularJS has error ... read »
May 25, 2013 at 9:53 PM
Nested Views, Routing, And Deep Linking With AngularJS
@Mrsean2k, I'm glad I could help! I haven't been able to keep up with the ui-router stuff. I keep saying that I'll carve out time, but I just haven't gotten to it :( ... read »
May 25, 2013 at 9:49 PM
What If All User Interface (UI) Data Came In Reports?
@Jonah, Thanks for the book recommendations. I am looking them up right now. I can see that Object Thinking is available for the Kindle App - sweet! Also, I just recently heard Martin Fowler on the ... read »
May 25, 2013 at 9:41 PM
HashKeyCopier - An AngularJS Utility Class For Merging Cached And Live Data
@Chris, I'm super excited to hear that my posts are helpful. I am also loving AngularJS; but, it definitely has some caveats and some odd behaviors and some things that just don't seem to "wor ... read »
May 25, 2013 at 9:36 PM
Ask Ben: Manually Enforcing Basic HTTP Authorization In ColdFusion
@Adam, @Jason, After reading these comments, I double-checked my latest implementation and I am happy to report that I am using listFirst() and listRest(). ... read »
May 25, 2013 at 9:31 PM
Using "//" And ".//" Expressions In XPath XML Search Directives In ColdFusion
@Daxesh, I am not sure I understand the question about the current node. If you already have a reference to the current node, why would you need to query for it? As for parent node, I believe that ... read »
May 25, 2013 at 10:08 AM
Using "//" And ".//" Expressions In XPath XML Search Directives In ColdFusion
@Ben, my question is that i want the current node with its tag and its parent node. i just want only that data. So, give me the solution for that. and remember solution is working on " xpath 1.0 ... read »
May 25, 2013 at 10:01 AM
Using "//" And ".//" Expressions In XPath XML Search Directives In ColdFusion
hey ben, i want get my current node tag and also want the root node tag withing. So, how can i fix it.. ! ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools