16 Replies Latest reply on Mar 23, 2011 12:15 PM by rapidray

    Request Scope & CFC called by Bind

    rapidray

      I am using CF9 in a windows 64bit environment.  I am using AJAX  functionality to populate a select list with values depending upon the  selection of a radio button.  I had this working in CF8, but I had  hardcoded the datasource, userid, and password for stored procedure  calls within the CFC.  In my new hosting environment, this is no longer  desirable. I tokenized these values by creating variables in the REQUEST  scope; defining them in my Application.cfc file.  It appears that a CFC  called through an AJAX bind does not receive the REQUEST scope and  therefore these variables are unavailable within functions residing in  the CFC.  Furthermore, it seems that the GetAuthUser() function does not  work either.  It appears to return an empty string instead of the  userID of the current logged in user.  I have attempted to kludge this  problem by passing these values out of the calling CFM as parameters to  the functions contained in the CFC.  While this works it has an  undesirable side-effect.  Previously (when only passing a form variable)  clicking on a radio button would immediately populate the select list  with the appropriated data based upon the button selected; but now, the  nothing happens when the user clicks on a radio button.  Then when the  users clicks on the select list, it suddenly re-populated.  Does anyone  know of a resolution to either the timing of populating the select list  in this context, or how to get the CFC to recognize the REQUEST scope  and the GetAuthUser() function...  Thanks

        • 1. Re: Request Scope & CFC called by Bind
          Dan Bracuk Level 5

          The request scope is inappropriate for what you want to do because the cfc was not part of the page request.  You are accessing it afterwards.

           

          For the radio button, what event are you using to call your js?

          • 2. Re: Request Scope & CFC called by Bind
            Adam Cameron. Level 5

            Hang on a sec, Dan: you're a bit quick off the mark there.  The AJAX request might not be part of the same request (and accordingly request scope) as the initial page load, but it still makes a request, and still has its own request scope.  And if request.dsn - or whatever - is set in onRequestStart, then it will be set for the AJAX requests too.  Provided, like, the same Application.cfc is running, of course.

             

            --

            Adam

            • 3. Re: Request Scope & CFC called by Bind
              Adam Cameron. Level 5

              It appears that a CFC  called through an AJAX bind does not receive the REQUEST scope and  therefore these variables are unavailable within functions residing in  the CFC.

               

              I can't vouch for the getAuthUser() stuff... never used it.  However I can repudiate the assertion above.  An AJAX request certainly does have a request scope, and certainly does run onRequestStart().  Is that where you're setting your request-scoped variables?

               

              Can you pls post the calling code, the code being called by the AJAX request, plus the relevant bits of your Application.cfc.

               

              You can verify that your onRequestStart handler is being called by putting a CFLOG entry in it, btw (troubleshooting tip...).

               

              --

              Adam

              • 4. Re: Request Scope & CFC called by Bind
                Dan Bracuk Level 5

                Not that I actually know any of this, but, my understanding is that Application.cfm/cfc files have influence when a .cfm page that is part of the application is called by an http request.  I don't see how this would happen with a javascript request to a cfc.

                 

                There certainly is a request, but I don't think any request variables are being set.

                • 5. Re: Request Scope & CFC called by Bind
                  Adam Cameron. Level 5

                  An HTTP request is an HTTP request.  Neither the web server nor CF distinguish between someone hitting a URL by typing it into the address bar of a browser, or clicking a link, or a frameset loading its frames, or an AJAX request being made.  All those things are browser conceits, and the server at the other end is unaware of those details.  All the web server (and, by proxy, the CF server) see are requests.  There is no difference at all.

                   

                  --

                  Adam

                  • 6. Re: Request Scope & CFC called by Bind
                    Dan Bracuk Level 5

                    Ya but,

                     

                    on an ajax request to a cfc, what exactly is it that inspires Application.cfc, or any other template for that matter, to set a request varialbe?

                    • 7. Re: Request Scope & CFC called by Bind
                      Dave Watts Adobe Community Professional

                      The same thing that causes it in response to a "regular" HTTP request from your browser. HTTP is HTTP.

                       

                      Dave Watts, CTO, Fig Leaf Software

                      http://www.figleaf.com/

                      http://training.figleaf.com/

                      • 8. Re: Request Scope & CFC called by Bind
                        Adam Cameron. Level 5

                        As per above, neither the web server nor CF know (or care) that it's "an AJAX request".  It's just a request.  Same as any other request.  There is nothing inate about an AJAX request that makes it any different from any other HTTP request.

                         

                        Turn the situation around... what is it about an AJAX request that makes you think it is any different from any other sort of request?

                         

                        --

                        Adam

                        • 9. Re: Request Scope & CFC called by Bind
                          Dan Bracuk Level 5

                          Regarding, "Turn the situation around... what is it about an AJAX request that makes you think it is any different from any other sort of request?"

                           

                          This particular request is not to a .cfm file.  That being the case, it is unlikely that an Application.cfm/cfc file will be activated and that's the file that likely sets the variables in the request scope.

                          • 10. Re: Request Scope & CFC called by Bind
                            Adam Cameron. Level 5

                            This particular request is not to a .cfm file.  That being the case, it is unlikely that an Application.cfm/cfc file will be activated and that's the file that likely sets the variables in the request scope.

                             

                            CF doesn't make that distinction.  A CF file is a CF file, and any request to a CF file - be it a CFM or a CFC - fires Application.cfc (or .cfm).

                             

                            --

                            Adam

                            • 11. Re: Request Scope & CFC called by Bind
                              Dave Watts Adobe Community Professional

                              Calling CFCs causes Application.cfc to be run if it's within the same directory or a parent directory, etc, just like running CFM files. This is why you can break certain features of CFCs by using the onRequest event in your Application.cfc.

                               

                              Dave Watts, CTO, Fig Leaf Software

                              http://www.figleaf.com/

                              http://training.figleaf.com/

                              • 12. Re: Request Scope & CFC called by Bind
                                rapidray Level 1

                                Here are sub-sets of the three files that inter-relate and with which I have a problem. As stated, originally the CFC lived together with the A_Report.cfm's directory.  Since I could not make CF9 find the CFC, I moved it to a new directory under the WEBroot.  (This may be the source of the problem since it no longer lives under the application.cfc'root directory.)  At any rate in it's new location, I needed to pass all the SESSIONinformation into the functions as well as the results of the GetAuthUser() function sincenone of this information was available withing the functions in the CFC. Originally, I onlyneeded to send the1st parameter of each of these functions since the other informationwas available.  Before I added the new parameters, when a user clicked on the one of theradio buttons the drop-down list and establishment name (if applicable) was populated.Now, upon clicking the radio button, nothing happens until the user clicks on the drop-downlist and then suddenly it repopulates itself.  The only differences in the code are thelocation of the CFC file, the fact that I tokenized the DB login values instead of havingthem hard-coded, and since SESSION variables were not recoginized, I added the parametersto the bind calls.

                                 

                                Because of security concerns of folks I work for, I have changed a number of names that
                                relate to the  actual purpose of the form and the application from which this stuff is extracted.

                                 

                                If the problem is the location of the CFC file vis-a-vis the application.cfc file, can someone explain how to make CF9 recognise a location other than under the WEB root.  I have tried creating a CF mapping, and it originally co-existed with the calling CFM...  But alas... It prefered the WEB root.

                                 

                                 

                                 

                                <!---   Application CFC File -------------------------------------------------------------- --->

                                 


                                <cfcomponent output="false">
                                    <cfset THIS.Name="App">
                                    <cfset THIS.scriptProtect="all">
                                    <cfset THIS.SessionManagement="Yes">
                                    <cfset THIS.ClientManagement="Yes">
                                    <cfset THIS.SetClientCookies="No">
                                    <cferror TYPE="validation" TEMPLATE="/shared/Error_InputFieldValidation.cfm">
                                    <cferror TYPE="EXCEPTION"  mailTo="me@home.here" TEMPLATE="/shared/Error_ProgramExceptions.cfm">
                                    <cferror TYPE="REQUEST"    mailTo="me@home.here" TEMPLATE="/shared/Error_Request.cfm">
                                   
                                    <cffunction name="onRequestStart" returnType="boolean" output="true">
                                            <CFSET REQUEST.ds=          "THEDATASOURCE">
                                            <CFSET REQUEST.wusr=        "THEPRIMARYUSER">
                                            <CFSET REQUEST.ausr=        "THESECONDARYUSER">
                                            <CFSET REQUEST.wpwd=         "PrimaryUsersPassword">
                                            <CFSET REQUEST.apwd=         "SecondaryUsersPassword">
                                    <cfreturn true>
                                    </cffunction>
                                </cfcomponent>

                                 

                                 

                                 

                                 

                                 

                                <!--- A_Report.CFM  ----------------------------------------------------------------------- --->

                                 

                                <CFINCLUDE TEMPLATE="/revpath/Manager_Login.cfm">
                                <CFINCLUDE TEMPLATE="/shared/FunctionHeader.cfm">

                                 

                                <CFIF NOT isdefined("RptStep")>
                                    <HTML>
                                    <HEAD>
                                    <TITLE>A Report</TITLE>
                                    <LINK type="text/css" rel="stylesheet" media="screen" href="/shared/Appstyle.css">
                                    </HEAD>

                                 


                                    <BODY>
                                    <CFOUTPUT>#AppPageHeader("Generate an OSHA 300 Privacy List")#</CFOUTPUT>
                                    <div id="outer">
                                         Just some header Information for the user
                                    </div>

                                 

                                    <CFFORM ACTION="A_Report.cfm?#CLIENT.urlToken#" METHOD=POST >
                                    <INPUT type="hidden" NAME="RptTitle_Required">
                                    <INPUT TYPE="hidden" NAME="RptStep" VALUE="View">
                                    <INPUT type="hidden" NAME="firstpass" VALUE="Yes">

                                 

                                    <FIELDSET Class="input-form-fieldset">
                                    <LEGEND Class="input-form-legend">SMIS Report Set-up:</LEGEND>
                                        <br/><br/>
                                        <CFOUTPUT>
                                        <LABEL for="batch"><A href="#REQUEST.helppath#/hlpRept-Batch.cfm" target="top">Select Organizations From:</a></label> 
                                        </CFOUTPUT>
                                        <CFINPUT TYPE="Radio" Name="usebatch" value="1" CHECKED><B>Batch File</B>  
                                        <CFINPUT TYPE="Radio" Name="usebatch" value="0"><B>Access List</B>  
                                        <CFINPUT TYPE="Radio" Name="usebatch" value="2"><B>Establishment</B>
                                        <br/><br/>

                                 

                                        <LABEL for="orgchoice"><A href="#REQUEST.helppath#/hlpRept-PickOrgs.cfm" target="top">Select Organizations:</a></label> 
                                        <CFSELECT NAME="orgchoice" Bind="cfc:CFCs.OrgData.GetOrgChoices({usebatch},'#getauthuser()#','#REQUEST.ds#','#REQUES T.wusr#','#REQUEST.wpwd#')" BindOnLoad="yes" display="OrgName" value="Org_ID" />

                                 

                                        <!---
                                        Originally (on the working version of this), the CFC was located in the same directory as this template...
                                        I can't speak for the REQUEST scope values (since I had these hard coded in the CFC), but the getauthuser(),
                                        call returned the correct user ID & now it returns nothing, so I passed it into the CFC as well.  I don't
                                        know exactly how it worked, but clicking on one of the radio buttons above always re-populated the
                                        list & the Establishment Name, as well as other stuff (not present in this model).
                                        Now, it is populated on load of form, but when radio button is clicked nothing happens until
                                        the user clicks the drop-down list at which time it re-populates itself.

                                 

                                        The original line of code follows:

                                 


                                        <CFSELECT NAME="orgchoice" Bind="cfc:OrgData.GetOrgChoices({usebatch})" BindOnLoad="yes" display="OrgName" value="Org_ID" />
                                        --->

                                 

                                        <br/><br/>

                                 

                                        <LABEL for="ename"><A href="#REQUEST.helppath#/hlpRept-EstabName.cfm" target="top">Establishment Name</a>:</label> 
                                        <CFINPUT ID="ename" Class="Input-Box" Type="Text" Size="60" Name="RptTitle" MaxLength="60"
                                                 Bind="cfc:CFCs.OrgData.GetEstabName({orgchoice},'#REQUEST.ds#','#REQUEST.wusr#','#REQUEST .wpwd#')"
                                                 Required="Yes" Message="The Establishment Name (Organization Name) is required for the Report" /><br/><br/>

                                 


                                        <INPUT Class="submit-button" Type=submit Value="Send this Info >>">
                                    </FIELDSET>
                                    </CFFORM>
                                    </body>
                                    </html>
                                <CFELSEIF #RptStep# is "View">
                                    <!--- More code::: irrelevent to this case --->

                                 

                                </CFIF>

                                 

                                 

                                 

                                <!--- The CFC file ----------------------------------------------------------------------------------------- ---------- --->

                                 

                                <!---
                                    Here is a portion of the CFC that does not seem to understand REQUEST variables,
                                    and evidently SESSION variables either (I'm assuming that is where getAuthUser() must
                                    get it's information.  This file is located under the inetpub\wwwroot\CFCs directory
                                    I couldn't get CF 9 to find it anywhere else
                                --->

                                 

                                <CFCOMPONENT>
                                    <CFFUNCTION Name="GetOrgChoices" Access="Remote" returnType="Query">
                                        <CFARGUMENT NAME="TypeofChoice" Type="Numeric" Default=1>
                                        <CFARGUMENT NAME="user"   Type="String">
                                        <CFARGUMENT NAME="dbds"   Type="String">
                                        <CFARGUMENT NAME="dbuser" Type="String">
                                        <CFARGUMENT NAME="dbpwd"  Type="String">

                                 

                                        <CFIF TypeOfChoice eq 0>
                                            <CFSTOREDPROC PROCEDURE="WEB_Ajax_GetAccessList" DATASOURCE="#dbds#" USERNAME="#dbuser#" PASSWORD="#dbpwd#">
                                                <CFPROCPARAM TYPE="In" MAXLENGTH="12" CFSQLTYPE="CF_SQL_VARCHAR" VALUE="#user#">
                                                <CFPROCRESULT NAME="data">
                                            </CFSTOREDPROC>
                                        <CFELSEIF TypeOfChoice eq 1>
                                            <CFSTOREDPROC PROCEDURE="WEB_Ajax_Get_SManager_Batches" DATASOURCE="#dbds#" USERNAME="#dbuser#" PASSWORD="#dbpwd#">
                                                <CFPROCPARAM TYPE="In" MAXLENGTH="12" CFSQLTYPE="CF_SQL_VARCHAR" VALUE="#user#">
                                                <CFPROCRESULT NAME="data">
                                            </CFSTOREDPROC>
                                        <CFELSEIF TypeOfChoice eq 2>
                                            <CFSTOREDPROC PROCEDURE="WEB_Ajax_Get_Estabs_Drillable" DATASOURCE="#dbds#" USERNAME="#dbuser#" PASSWORD="#dbpwd#">
                                                <CFPROCPARAM TYPE="In" MAXLENGTH="12" CFSQLTYPE="CF_SQL_VARCHAR" VALUE="#user#">
                                                <CFPROCPARAM TYPE="In" MAXLENGTH="13" CFSQLTYPE="CF_SQL_VARCHAR" VALUE="SafetyManager">
                                                <!--- The constant "SafetyManager may be replaced with the function "#GetUserRoles()#" when CF8 is deployed --->
                                                <CFPROCRESULT NAME="data">
                                            </CFSTOREDPROC>
                                        <CFELSE>
                                            <div id="urgent">
                                            Invalid value received for choice of organization list in OSHA 300 Log Report!
                                            </div>
                                            <cfabort>
                                        </CFIF>
                                        <CFRETURN data>
                                    </CFFUNCTION>

                                 


                                    <CFFUNCTION Name="GetEstabName" Access="Remote" returnType="String">
                                        <CFARGUMENT NAME="EstablishmentID" Type="String" Default="">
                                        <CFARGUMENT NAME="dbds"   Type="String">
                                        <CFARGUMENT NAME="dbuser" Type="String">
                                        <CFARGUMENT NAME="dbpwd"  Type="String">

                                 

                                            <CFSTOREDPROC PROCEDURE="WEB_Ajax_GetEstabName" DATASOURCE="#dbds#" USERNAME="#dbuser#" PASSWORD="#dbpwd#">
                                                <CFPROCPARAM TYPE="In" MAXLENGTH="11" CFSQLTYPE="CF_SQL_VARCHAR" VALUE="#EstablishmentID#">
                                                <CFPROCRESULT NAME="estabname">
                                            </CFSTOREDPROC>
                                            <CFRETURN #estabname.Estab_Name#>
                                    </CFFUNCTION>

                                 

                                   </CFCOMPONENT>

                                • 13. Re: Request Scope & CFC called by Bind
                                  rapidray Level 1

                                  By the way... Thank you all who are helping me with this issue!!

                                  • 14. Re: Request Scope & CFC called by Bind
                                    Adam Cameron. Level 5
                                    Since I could not make CF9 find the CFC, I moved it to a new directory under the WEBroot.  (This may be the source of the problem since it no longer lives under the application.cfc'root directory.) 

                                     

                                    Well: yes.  That's your problem (well: it's enough of a problem I didn't bother reading the rest of your post... they might be more problems after that).

                                     

                                    If the request variables are set in an Application.cfc file, and your CFC requests aren't going to call that Application.cfc... how do you expect the request variables to exist? ;-)

                                     

                                    What you need to do is to drop an Application.cfc into the dir that the CFC(s) are in that extends the other Application.cfc.

                                     

                                    Tell me: if you suspected that was the problem, why didn't you investigate that angle?

                                     

                                    --

                                    Adam

                                    • 15. Re: Request Scope & CFC called by Bind
                                      rapidray Level 1

                                      Quite frankly, Adam, it did not occur to me until I was assembling the code (at the request of someone in this forurm) for the post.  I'm still not convinced that this is completely solved since the GetAuthUser() function gets it's info elsewhere (I think), and I would prefer (if at all possible) to have a single application.cfm driving the whole show, not have them scattered about the WEB site.  Right now we are going through a significant port moving to a completely new hosting enviromnment, Changing form Windows Server 2003 to 2008R2, SQL Server 2005 to 2008, Cold Fusoion 8 to CF 9, and 32 bit to 64 bit.  So I am encountering lots of "little" issues along the way.  It would really help if I could find a way to get CF9 to recognize a location of my CFC UNDER or along side of the app's application CFC.  But I will be expermenting with this some more today.  I'll post tonight whether all is well or not....  Thanks again for the help...

                                      • 16. Re: Request Scope & CFC called by Bind
                                        rapidray Level 1

                                        Adam & Others,   I finally got the CFC to be located in a directory under my application.cfm root and was able to make the code work... Kind-of.  In-fact (and this is an egg on my face moment) I discovered that it works exactly as before INCLUDING a problem with IE, that I didn't realize existed.  I have tested the code in Chrome, Firefox, and Safari and it works perfectly; that is... when a radio button is clicked, the drop-down list populates with the appropriate values.  BUT in IE, nothing happens until the drop down list is clicked, at which time it re-populates the list.  Using the code that I referenced above (excluding the passed variables that go beyond the "form" scope) does anyone know how to make IE behave like the other browsers.  So my problem with the Session scope has been resolved, but I still have this sort-of klunky behavior exibited by IE and unfortunately, my population is probably 95% IE dependent.