put argument's struct in variables scope

397 views Asked by At

I want to easily put an argument's struct contents into the variables scope for all functions of a component. 'Title' is one of the searchitems struct.

<cffunction name="setSearch" acces="public" returntype="void">    
     <cfargument name="searchitems" type="struct" required="true" />
     <cfset variables = arguments.searchitems>
     <cfset variables.test = "yo">           
</cffunction>

<cffunction name="testit" acces="public" returntype="void">
    <cfdump var="#variables.test#"><br>
    <cfif isdefined('variables.test')>found in variables.test  </cfif>
    <cfif isdefined('variables.variables.test')>found in variables.variables.test </cfif>
    <hr>
    <cfdump var="#variables.title#"><br>
    <cfif structkeyexists(variables,'title')>found in variables.title with structkeyexists </cfif>
    <cfif structkeyexists(variables.variables,'title')>found in variables.variables.title with structkeyexists</cfif>
    <cfif isdefined('variables.title')>found in variables.title </cfif>
    <cfif isdefined('variables.variables.title')>found in variables.variables.title</cfif>
</cffunction>

however running this gives:

yo
found in variables.test

mytitletext
found in variables.variables.title with structkeyexists
found in variables.variables.title 

I find this strange that title can be dumped or output as variables.title but it can't be detected with isDefined or structkeyexists. Is there a more efficient way to assign

<cfset variables = arguments.searchitems> 
2

There are 2 answers

1
Lucas On

Use the component's "this" scope.

<cfcomponent>

<cfset this.myArgs = StructNew()>
<cfset this.test = "">


<cffunction name="setSearch" acces="public" returntype="void">    
     <cfargument name="searchitems" type="struct" required="true" />
     <cfset this.myArgs= arguments>
     <cfset this.test = "yo">           
</cffunction>

</cfcomponent>
0
CfSimplicity On

I'd recommend following Adam's advice and keeping your searchitems in their own separate struct in the variables scope rather than as individual items. That way you don't risk overwriting other variables.

Test.cfc

<cfcomponent>

    <cffunction name="init">
        <!--- Set up a separate empty container for the searchitems to be available to all functions --->
        <cfset variables.searchitems = StructNew()>
        <cfreturn this>
    </cffunction>

    <cffunction name="setSearch" returntype="void">    
        <cfargument name="searchitems" type="struct" required="true">
        <!--- Fill the container with the struct passed into this function --->
        <cfset variables.searchitems = arguments.searchitems>
    </cffunction>

    <cffunction name="dumpSearchTitle" returntype="void">
        <cfdump var="#variables.searchitems.title#">
    </cffunction>

</cfcomponent>

index.cfm

<cfscript>
    request.searchitems = StructNew();
    request.searchitems.title = "mytitletext";
    test = CreateObject( "component", "test" );
    test.setSearch( request.searchitems );
    test.dumpSearchTitle();
</cfscript>

However, if it's really important to have the individual searchitems in the variables scope, then you could append them to the variables scope. The third, false parameter of StructAppend ensures you don't overwrite existing variables.

Test.cfc

<cfcomponent>

    <cffunction name="init">
        <cfreturn this>
    </cffunction>

    <cffunction name="setSearch" returntype="void">    
        <cfargument name="searchitems" type="struct" required="true">
        <cfset StructAppend( variables,arguments.searchitems,false )>
    </cffunction>

    <cffunction name="dumpSearchTitle" returntype="void">
        <cfdump var="#variables.title#">
    </cffunction>

</cfcomponent>