Application.cfc Scoped Functions Are Stored In Page VARIABLES Scope

Posted November 6, 2006 at 2:31 PM

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:

 Launch code in new window » Download code as text file »

  • <!--- 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.

Download Code Snippet ZIP File

Post Comment  |  Ask Ben  |  Other Searches  |  Print Page





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 »
7,572 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 »
7,572 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 »
7,572 Comments

@Lems,

Ok cool. Good luck.


Mar 16, 2009 at 4:06 PM // reply »
18 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 »
18 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 »
7,572 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 »
18 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 »
7,572 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 »
7,572 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 »
18 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 »
18 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 »
7,572 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 »
18 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 »
7,572 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 »
18 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 »
7,572 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 Comment  |  Ask Ben

Recent Blog Comments
Mar 22, 2010 at 3:08 AM
Ask Ben: Selecting XML Attributes Given Other XML Attributes
Thanks for the response. I finally discovered that I was getting this error because I had cfsetting enablecfoutputonly="yes" in Application.cfc, and was neither setting it to false elsewhere nor brac ... read »
Mar 21, 2010 at 8:57 PM
The Bourne Ultimatum Starring Matt Damon And Julia Stiles
late to the party, but my observation is this: rewatch carefully for the platonic nature of the relationship between nicki and jason. she never flirts with him. he never comes on to her. they alway ... read »
Mar 21, 2010 at 7:40 PM
Is Simulating User-Input Events With jQuery Ever A Good Idea?
A couple of things. One you embed the initial state of of more-info in the CSS. IMHO, that behavior should be in jQuery: moreInfo.hide(); It shows that the behavior your toggling and closing is mor ... read »
Mar 21, 2010 at 3:59 PM
Exploring ColdFusion Component Runtime Class Properties And Serialization
@Elliott, according to Ben's experiment, serializeJSON() doesn't access the private data by default - it doesn't even access the getHair() method - so trying to clone a Girl.cfc via serializeJSON/des ... read »
Mar 21, 2010 at 3:49 PM
Ask Ben: Javascript String Replace Method
I'm confused a bit by what you are asking, but if had this sentence: The color, red, is in the style statement; style: red;. and wanted to remove all or change all of the commas, colons, and semi-c ... read »
Mar 21, 2010 at 3:13 PM
Ask Ben: Javascript String Replace Method
I am trying to make a java program to count the number of times that these punctuation marks occur in a body of text: , : ; . ! - ' " ? / \ I am using this piece to ferret out the commas: numcommas ... read »
Mar 21, 2010 at 11:13 AM
A New Wrist Pain
@chiropractor suwanee, Spoken like someone trying to sell something. Other than for minor, temporary relief from some back pain, chiropractic treatment is nothing but placebo effect and quackery. ... read »
Mar 21, 2010 at 6:32 AM
ColdFusion CFPOP - My First Look
Apologies... The field name in the db for C. is "BounceCode" It stores the code / message which is returned in the email. Sorry for the confusion. ... read »