10 Replies Latest reply on Feb 4, 2009 11:26 AM by Duke Snyder

    application.cfm and CFC's

    Duke Snyder
      for some reason my cfc is not seeing any of the variables set in application.cfm. Furthermore it does not see them when I use application.cfc. I am running 6.1MX on iis5. Any info would be helpful.

      Thanks
        • 1. Re: application.cfm and CFC's
          JR "Bob" Dobbs-qSBHQ2 Level 3
          If you can provide the following information it will be easier to help you.

          1. Your code, including application.cfm, your CFC, and whatever code is calling the CFC. Since you are using CFCs please also describe your directory structure.

          2. Can you describe the desired output and what output or error messages you actually get?


          I believe that the application.cfc file was introduced in CF7 so it will not work in CF6 (someone please correct me if I am mistaken). You will need to use an application.cfm file instead.
          • 2. Re: application.cfm and CFC's
            Level 7
            > for some reason my cfc is not seeing any of the variables set in
            > application.cfm. Furthermore it does not see them when I use application.cfc. I
            > am running 6.1MX on iis5. Any info would be helpful.

            6.1 doesn't have the concept of "Application.cfc", so that explains that
            bit. It was introduced in 7.

            But it's difficult to make much more comment on why your code's not working
            in the Application.cfm scenario without... you know... you showing us what
            the code actually is. It's a bit hard to just guess. Well I suppose we
            could, but it's gonna be a loooong night...

            --
            Adam
            • 3. Re: application.cfm and CFC's
              Level 7
              Duke Snyder wrote:
              > for some reason my cfc is not seeing any of the variables set in
              > application.cfm. Furthermore it does not see them when I use application.cfc. I
              > am running 6.1MX on iis5. Any info would be helpful.
              >
              > Thanks
              >

              In deference to Adam, I'm going to go ahead an make a guess. :-)

              Directory structure is very important here. Application.cfm will only
              apply to code that is run in the same directory or any sub directory
              there under. This applies to CFC's as well. A common idea is to place
              a CFC in some type of common folder that is outside the normal
              application structure, thus the CFC is not in the directory structure
              under which the Application.cfm file has dominion. So it will not apply
              in such a case.

              If this is so, the fix is to either move the CFC so that it is under the
              Application.cfm dominion. Or to provide it it's own <cfapplication...>
              tag with the desired application name to be able to access the desired
              application scope. This can be done directly in the CFC file or an
              Application.cfm file in the CFC folder hierarchy.

              Of course doing so really complicates the usefulness of having CFCs in a
              common place where they can be used by multiple applications equally.
              Thus providing a strong argument to the OOP concept of encapsulation.
              That an object (component) should not be aware of anything outside of
              itself and everything it needs to do its job should be passed into it.

              I.E. Pass the required application data into the component as arguments
              and make use of it that way.
              • 4. Re: application.cfm and CFC's
                Duke Snyder Level 1
                Well adam explained why the cfc wont see application.cfc as 6.1 does not support it. BUT why the cfc wont see the variables in application.cfm is another issue.

                I am setting my dsn in application.cfm like so;

                <cfset dsn = 'mydsn'>

                the application.cfm resides in the root directory of the site. My cfc is called master.cfc and resides in a subdirectory of the root called "components". There are no other application.cfm files in the root. Below is one of the functions in master.cfc. When I invoke the function It errors out as is with "dsn is not defined". If I replace it with the actual datasource name it works fine.

                <cfcomponent>
                <cffunction name="GetMerch" access="public" output="false" returntype="query" hint="Returns Merchants based on merchant types">
                <cfquery name="QGetMerch" datasource="#dsn#">
                SELECT * FROM allmerchants where 0=0
                <cfif arguments.merchtype is 'All'>and new_cat = '#arguments.catid#' and active = '1'
                <cfelse>and merch_type = '#arguments.merchtype#' and new_cat = '#arguments.catid#' and active = '1'
                </cfif>
                <!---[ if we are calling canadian merchants we add this ]--->
                <cfif arguments.canadian is 'y'> and canadian = 'y'
                </cfif>
                order by name
                </cfquery>
                <cfreturn QGetMerch />
                </cffunction>
                <cfcomponent>

                Thanks for the effort.
                • 5. Re: application.cfm and CFC's
                  Level 7
                  when you set application scope variables, you must prefix them with
                  Application. :

                  <cfset application.dsn = "mydsn">

                  then in your cfc access the variable as #application.dsn#:
                  <cfquery name="QGetMerch" datasource="#application.dsn#">

                  you should also VAR your variables in cfc (query name in your case):

                  <cffunction ...>
                  <cfargument ...
                  <CFSET VAR QGetMerch = "">
                  <cfquery name="QGetMerch" ...>
                  ...

                  Azadi Saryev
                  Sabai-dee.com
                  http://www.sabai-dee.com/
                  • 6. Re: application.cfm and CFC's
                    JR "Bob" Dobbs-qSBHQ2 Level 3
                    The dsn variable is not visible to code within your CFC.

                    From the CF8 docs, this should also apply to version 6 (someone please correct me if I am mistaken).
                    "The CFC Variables scope does not include any of the Variables scope variables that are declared or available in the page that instantiates or invokes the CFC."
                    http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=buildingComponents_29.ht ml

                    I'd put the dsn variable into the request or application scope. This will make the variable accessible within your CFCs.
                    • 7. Re: application.cfm and CFC's
                      Level 7
                      Azadi and JR have already discussed why your CFC is not seeing the
                      _local_ variables scope 'DSN' variable that you are setting in the
                      Applicaiton.cfm file. Components just don't share the local scope with
                      the template that calls them, they are not supposed to. They both
                      pointed out that if you declared this variable in a global scope such as
                      application or request, you could use it from there in all your code.

                      But I am going to reinforce that this is generally a bad idea.
                      Components should not be getting their data from outside of themselves.

                      A better approach might be something like this.

                      <cffunction name="GetMerch"...>
                      <cfargument name="DSN" type="string" required="true">
                      <cfset var QGetMerch = ""> <!--- creates a local variable for this
                      function as described by Azadi --->

                      <cfquery name="QGetMerch" dataSource="#arguments.DSN#">
                      ...



                      Then when you call the function pass in the DSN.

                      <cfinvoke ...>
                      <cfinvokeArgument name="DSN" value="#variables.dsn#">
                      </cfinvoke>

                      OR

                      <cfinvoke ... DSN="#variables.dsn#/>

                      OR

                      <cfset something=createObject("component","path.to.compnent")>
                      <cfset aQry = something.GetMerch(variables.dsn)>

                      OR

                      Other methods.
                      • 8. Re: application.cfm and CFC's
                        Level 7
                        > OR
                        >
                        > Other methods.

                        I'd rather pass the DSN value into the CFC's init() method, rather each
                        methods that might need to use it:

                        <cfset myResult = createObject("component",
                        "myComp").init(dsn=dsn).method()>

                        Or:

                        <cfset oComp = createObject("component", "myComp").init(dsn=dsn)>
                        <cfset myFirstResult = oComp.method1()>
                        <cfset myFirstResult = oComp.method2()>


                        Where init() looks like this:

                        function int(dsn){
                        variables.dsn = arguments.dsn;
                        }

                        Then the methods within the CFC just use variables.dsn locally.

                        --
                        Adam
                        • 9. Re: application.cfm and CFC's
                          Level 7
                          > application.cfm

                          Also, try to get into the habit of thinking of it as Application.cfm as
                          opposed to application.cfm (and equivalently Application.cfc).

                          At some point you're going to be working on a case-sensitive file system,
                          and it's a good habit to get into to use the correct file names.

                          It doesn't *matter* on Windows; it just looks like lack of attention to
                          detail.

                          --
                          Adam
                          • 10. Re: application.cfm and CFC's
                            Duke Snyder Level 1
                            Thanks JR "Bob" Dobbs
                            That worked fine. I have been working with CF for over 9 years and am finaly monkeying around with cfc's. As for the rest of the posts, all the advice was useful. Thanks.