2
votes

If this has been asked before I apologize but I wasn't able to get a solid enough understanding without some assistance ....

I have a Local ColdFusion9 App that I use for development and testing running on WinXP SP3 with Apache 2 ...

What I'm having a problem understanding how to call request elements passed from the Application's 'THIS' scope to the onRequestStart() method.

For instance, My Application.cfc has the following in 'THIS' ...

<!--- MY 'THIS' Statements in Application.cfc --->

<cfscript>

/* define custom coldfusion mappings. Keys are mapping names, values are full paths  */
this.mappings = structNew();
this.mappings['/tags'] = ExpandPath('/cfdev/tags');

</cfscript>

Further into my Application.cfc I have the following in the onRequestStart() function ...

<!--- Run before the request is processed --->
<cffunction name="onRequestStart" returnType="boolean" output="false">
    <cfargument name="thePage" type="string" required="true">
        <cfinclude template="#arguments.thePage#">

<!--- Lot's of onRequest statements and then ... --->

    <cfset request.mappings = #THIS.mappings#>

    <cfreturn true>
</cffunction>

Now ... Supposing I have a page where I call <cfdump var="#request.mappings#"> ...

I get an error stating

'Element MAPPINGS is undefined in REQUEST.' ...

However, (here's where my confusion begins) ... If I call <cfdump var="#request#"> Two structures are returned ... The first containing a key for "cfdumpinited" with a value of 'False' and the second with the structKey 'mappings' which contains another struct with a key of '/tags' and a value of 'C:\vir_dir\CFDEV\tags' as one would expect ...

If someone could please explain why it is that request succeeds yet request.mappings fails as I'm a bit in the woods here ... ;-)

2
FYI: I solved my own problem 'here' ... The solution was to access the structure's elements ... as such ... request['mappings']['/tags'] - Edward J Beckett
Perhaps this would work for you: request.mappings = structCopy(this.mappings); - Aaron Greenlee
@EddieB: Don't add your solution to the question or change the question title to include "solved". Instead, put your solution into an answer and mark that as the accepted answer. This will provide a guidepost for future readers and uses the system as it's designed. - ale
@Al ... Thanks too ... Noted for future reference ... :=) - Edward J Beckett
@Aaron ... Nope ... That doesn't work either ... Why? Adam was correct as he stated below ... the explicit struct copy happened after the requested page was delivered ... the variables were created after the fact ... :-) - Edward J Beckett

2 Answers

1
votes

Follow the logic through:

  1. a request is made
  2. onRequestStart runs
  3. you explicitly include the template requested
  4. youTHEN set request.mappings = this.mappings
  5. onrequeststart finishes
  6. the template requested executes

So if you have this in your requested template:

<cfdump var="#request.mappings#>

Then when you include that file at step 3... request.mappings doesn't exist yet (as they are created in step 4).

However when you change it to:

<cfdump var="#request#>

Then there's no error condition, so your CFINCLUDE runs fine, but DOESN'T OUTPUT ANYTHING (because you have output="false" on the function definition.

The dump you are seeing is the one coming from CF executing the requested template (step 6), by which time request.mappings exists.

I think you are confusing onRequestStart() with onRequest(), to be honest. It's in onRequest() that one might explicitly include the requested template, because onRequest() runs INSTEAD of CF running the requested template automatically. One would not generally include the requested template in onRequestStart() because it'll end up running twice.

Make sense?

0
votes

I'm late to the party here, and may be missing a key element, but why not do this:

application.mappings = structNew()

instead of

this.mappings = structNew()

that way, you only set them once (on application start), you have access to them across your whole application, and you don't have the extra overhead of setting the request scope on every page hit.