Reputation: 28483
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
Upvotes: 0
Views: 3661
Reputation: 11
You should map the variable to the data you pass, then no problem sending a struct. Do it this way
<cfset objMailer = createObject("component","mailer_user") />
<cfset objMailer.say_hi(userData:user.data)/>
This works even in CF7.
Upvotes: 1
Reputation: 28483
Ok. There was a typo inside my mailer CFC, where I had a variable with "##". As is was inside my email text it went unnoticed...
So you can pass a struct allright using this:
<cfinvoke component="mailer_user" method="say_hi">
<cfinvokeargument name="userData" value="#User.userdata#">
</cfinvoke>
and grab it inside your called function like so:
<cffunction name="say_hi" access="public" output="false" hint="">
<cfargument name="userData" type="struct" required="true" hint="user data passed" />
<cfscript>
var internalInfo = "";
var User = {};
User.userdata = userData;
</cfscript>
...
Maybe someone else can use the snippet.
Upvotes: 0
Reputation: 2438
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?
Upvotes: 3
Reputation: 32885
I think you should stay in cfscript style by writing
// call mailer
mailUser = createObject("component", "mailer_user"); // or new mailer_user(); for CF9+
mailUser.say_hi(User.data);
That should work, if it doesn't, it's somewhere else in your code. Try looking at the error log.
Upvotes: 2