Search code examples
coldfusionstructcfccfinvoke

How to pass a struct to Coldfusion CFC using CFINVOKE?


I have a CFC file which handles all of the emails I'm sending form an application (using Coldfusion8).

I was using CFINVOKE to call the respective function inside this CFC and passed a struct with all user data along like so:

<cfscript>  
var User.data = {};
    User.data.name = "John Doe";
    User.data.email = "[email protected]";
    ...
</cfscript>     
// call mailer
<cfinvoke component="mailer_user" method="say_hi">
    <cfinvokeargument name="userData" value="#User.data#">
</cfinvoke>

And inside my mailer.cfc

<cffunction name="say_hi" access="public" output="false">
    <cfargument name="userData" type="struct" required="true" /> 
 ....

For some reason this now fails and I can only get it to work if I pass fields seperately as cfargument, which is a a pain, since I'm passing a lot of data.

Question: How can I get this to work using argumentCollection.

Even if I CFINVOKE like this:

 <cfinvoke component="mailer_user" argumentcollection="#User.data#" method="say_hi"></cfinvoke>

it still doesn't do a thing. I'm setting output flags right before the cfinvoke and after, as well as inside the "say_hi" function going in and out. I'm only getting the flag before CFINVOKE.

Side note: This is all done through AJAX and I'm only getting back success="false" if my CFC has an error somewhere. I only work remotely on the system, so I can't set AJAX debugging in CFADMIN


Solution

  • As I typed the comment above it occurred to me what the problem is likely to be.

    You are passing in a structure to your function. You pass User.data which has name,email,blah,etc as keys in that structure. Those keys need to match the arguments in your function

    <cffunction name="say_hi" access="public" output="false">
        <cfargument name="name" type="struct" required="true" /> 
        <cfargument name="email" type="struct" required="true" /> 
        <cfargument name="blah" type="struct" required="true" /> 
        <cfargument name="etc" type="struct" required="true" /> 
    

    If you want to pass in the structure as a argument, you would need to have a user.userData as your structure of user data and your function should be

    <cffunction name="say_hi" access="public" output="false">
        <cfargument name="userData" type="struct" required="true" /> 
    

    When you pass the collection as argumentCollection you should do argumentCollection="#user#", so that the userData part matches your cfargument in the function.

    Clear as mud?