Expand my Community achievements bar.

Guidelines for the Responsible Use of Generative AI in the Experience Cloud Community.

Remote Object to CFC and back

Avatar

Level 2
I want to have in the url test.cfm?SupplierID=3



The file should send the variable SupplierID to a CFC and the
CFC send the data to the flex app. this is basicaly what I have for
the RO (there is a grid that gets filled in from the RO)



<mx:RemoteObject

id="qResult"

destination="ColdFusion"

source="invbl"

showBusyCursor="true" >



<mx:method name="Inventory"
result="handleQueryResult(event)"
fault="Alert.show(event.fault.message)"/>

<mx:method name="SupplierID">

<mx:arguments>

<supplierid>

{Application.application.parameters.SupplierID}

</supplierid>

</mx:arguments>

</mx:method>

</mx:RemoteObject>



I know the Application.application.parameters.SupplierID is
good because I have another part of my app that sends that to
another page where it gets the variable "3" just fine.



In my sample above Im not sure if thats how to make the
request.



my CFC looks like this:



<cfcomponent name="Inventory">

<cffunction name="Inventory" access="remote"
returnType="query" output="false">

<cfargument name="supplierid" required="no">



<CFQUERY NAME="Inventory" DATASOURCE="COREDATA">

SELECT PNUM5W, PDES5W, SDIVDE, ISCF3W, DIVN5W, COMC5W,
COMCDE, PGMJ5W, PGMJDE,

INV_51, ORD_51, SUBSTRING(DAT_51,4,2) + '/' +
SUBSTRING(DAT_51,6,2) AS DAT_51, INT_51,

INV_61, ORD_61, SUBSTRING(DAT_61,4,2) + '/' +
SUBSTRING(DAT_61,6,2) AS DAT_61, INT_61,

INV_71, ORD_71, SUBSTRING(DAT_71,4,2) + '/' +
SUBSTRING(DAT_71,6,2) AS DAT_71, INT_71,

INV_81, ORD_81, SUBSTRING(DAT_81,4,2) + '/' +
SUBSTRING(DAT_81,6,2) AS DAT_81, INT_81

FROM InvBL

<cfif structKeyExists(arguments, "supplierid")>

WHERE PGMJ5W = <cfqueryparam
value="#arguments.supplierid#" cfsqltype="cf_sql_varchar" />

</cfif>

ORDER BY PDES5W, SDIVDE, PNUM5W

</CFQUERY>



<cfreturn Inventory>

</cffunction>

</cfcomponent>



If I hard code a 3 in the place of the "arguments.supplierid"
the app works fine. so IM thinking that the CFC never gets the
variable. Can anyone tell me how to do this?



Thanks

George



8 Replies

Avatar

Level 3
Can you show me the code that actually calls your
RemoteObject? Do you just call send()?



Also, I think your MXML for the method of your RemoteObject
should be <mx:method name="Inventory"> as this is the name of
the CFC function you're looking to call.

Avatar

Level 2
So far its kinda like this im leaving some script out just to
simplify.



<mx:Application xmlns:mx="
http://www.adobe.com/2006/mxml"
layout="absolute" creationComplete="initVars()" >



<mx:Script>



[Bindable]

public var myData:ArrayCollection;



[Bindable]

public var SupplierID:String;



private function initVars() : void {

SupplierID = Application.application.parameters.SupplierID;

}

</mx:Script>



<mx:RemoteObject

id="qResult"

destination="ColdFusion"

source="invbl"

showBusyCursor="true" >



<mx:method name="Inventory"
result="handleQueryResult(event)"
fault="Alert.show(event.fault.message)"/>

<mx:method name="SupplierID">

<mx:arguments>

<supplierid>

{Application.application.parameters.SupplierID}

</supplierid>

</mx:arguments>

</mx:method>

</mx:RemoteObject>





There is a panel and grid and stuff here...



My CFC is like this:



<cfcomponent name="Inventory">

<cffunction name="Inventory" access="remote"
returnType="query" output="false">

<cfargument name="supplierid" required="no">



<CFQUERY NAME="Inventory" DATASOURCE="MyData">

SELECT PNUM5W, PDES5W, SDIVDE, ISCF3W, DIVN5W, COMC5W,
COMCDE, PGMJ5W, PGMJDE,

INV_51, ORD_51, SUBSTRING(DAT_51,4,2) + '/' +
SUBSTRING(DAT_51,6,2) AS DAT_51, INT_51,

INV_61, ORD_61, SUBSTRING(DAT_61,4,2) + '/' +
SUBSTRING(DAT_61,6,2) AS DAT_61, INT_61,

INV_71, ORD_71, SUBSTRING(DAT_71,4,2) + '/' +
SUBSTRING(DAT_71,6,2) AS DAT_71, INT_71,

INV_81, ORD_81, SUBSTRING(DAT_81,4,2) + '/' +
SUBSTRING(DAT_81,6,2) AS DAT_81, INT_81

FROM InvBL

<cfif structKeyExists(arguments, "supplierid")>

WHERE PGMJ5W = <cfqueryparam
value="#arguments.supplierid#" cfsqltype="cf_sql_varchar" />

</cfif>

ORDER BY PDES5W, SDIVDE, PNUM5W

</CFQUERY>



<cfreturn Inventory>

</cffunction>

</cfcomponent>



Thanks for looking

George

Avatar

Level 3
Sorry, I wasn't clear in my last post. Your MXML tag for
RemoteObject is incorrect... you have two <mx:method> tags,
but you should only have one:



<mx:RemoteObject

id="qResult"

destination="ColdFusion"

source="invbl"

showBusyCursor="true" >



<mx:method name="Inventory"
result="handleQueryResult(event)"
fault="Alert.show(event.fault.message)">

<mx:arguments>

<supplierid>

{Application.application.parameters.SupplierID}

</supplierid>

</mx:arguments>

</mx:method>

</mx:RemoteObject>

Avatar

Level 2
Thanks Peter,

I did take that out yesterday. So im calling the correct one,
inventory. BUT....

that did not help either. I did spend the whole day on this
and still no progress. I must be the dumbest

Thanks for hangen in there with me. I did read a post about
sending 2 variables one with a null or something. I tried that and
abunch of other stuff to no avail. I also have read a bunch a posts
claiming its a bug. If so this makes Flex useless for me. CF Flash
Forms is so easy compaird to this. I want this to work so bad. Lots
of big giant companies are relying on me to pull through. If I can
show them this works maybe they would consider Flex.



George

Avatar

Level 3

quote:




Originally posted by:
GeorgeWS


I did read a post about sending 2 variables one with a null
or something. I tried that and abunch of other stuff to no avail. I
also have read a bunch a posts claiming its a bug.





What you're trying to do is simple and in general it is
supported, something just must be confused in the code - we'll have
to work out what that is.



Note that post you mention about sending 2 variables - this
technique in Flash Remoting was to avoid an issue with CFC methods
as you have to help it distinguish that you're not sending named
arguments but one argument that is a single complex object. Named
arguments are like a struct of key-value pairs... and an
ActionScript Object does represent such a struct to CF. This method
of representing arguments would be unfamiliar to a Java or AS
developer as functions typically take ordered arguments. Anyway,
named argument confusion arises if you're sending a single
ActionScript Object to a CFC method - the Flash Remoting adapter in
ColdFusion can't get access to the real API of your CFC method (due
to certain internal limitations) to check the signature or number
of arguments so it has to assume that a single ActionScript Object
is a set of named arguments rather than a single parameter. If you
send a second argument after the Object, it knows it's not a set of
named arguments but instead its a list of plain old ordered
arguments. In order to send two arguments, however, your CFC method
signature needs to have at least two arguments defined
(obviously)... the first one would be of type struct to handle the
AS Object argument and the second can be anything... you can always
just ignore the second argument and not use it in your function.



The reason you may be hitting this problem is that you're
using MXML based syntax for arguments to take advantage of
automatic binding code. If you do choose this route, you need to
understand just what the MXML compiler is generating for your code:



<mx:method name="Inventory"
result="handleQueryResult(event)"
fault="Alert.show(event.fault.message)">

<mx:arguments>

<supplierid>

{Application.application.parameters.SupplierID}

</supplierid>

</mx:arguments>

</mx:method>



Note that the child of <mx:arguments> is seen just like
an <mx:Model>... a declarative view of an object graph. The
<supplierid> is seen as a property name, and the value is a
binding expression (in your case evaluating to the value 3). This
is equivalent to the following ActionScript:



arguments = new Object();

arguments["supplierid"] = 3;



So, you may indeed be sending an Object instead of just the
number 3?



You could check this in you CFC by looking whether
"#arguments.supplierid.supplierid#" is defined.



Whenever you're dealing with data communications you should
be aware of the ways to view the data being transmitted as without
it it makes debugging very difficult. Do you know about the debug
flashplayer's ability to trace out statements to a flashlog.txt
file? Are you familiar with the <mx:TraceTarget level="0" />
technique in Flex? Do you know about the ways of turning on debug
level logging for either Flash Remoting (setting logging level to
"debug" in gateway-config.xml) or Flex Data Services (setting
logging level to "debug" in services-config.xml) and looking at the
server logs (or the console if you started the app server on the
command line)?



Avatar

Level 2
Pete,

I look at the CFC and replaced my #arguments.supplierid# with
#arguments.supplierid.supplierid# and I get an error saying
undefined. I dont know much about the debugger either, mainly
because it requires setup and the CF plugin for communication
needed a very painful poorly documented setup and all this seems so
mickey mouse. Pretty much I want to run the debugger and have it go
through the progam line by line or something and show me whats set
and stuff but I dont know how. Im stumped without a sample. Im
confused about a bunch of stuff. When you say MXML compiler what do
you mean? I dont complie I just export. Where is the compile
button? I have never heard of the <mx:TraceTarget level"0"/>
. Pretty much I know nothing, it seems. I just want to send one
variable to my CFC. My remoteObject looks like other code samples
and my CFC looks like the samples. It just does not work.

Avatar

Level 3
There should have been numerous postings on forums about
setting up debug level logging for using Flash Remoting or Flex
requests with ColdFusion, but if you're not comfortable with this
another approach might be to redirect CFDUMP output (or some
equivalent) for the various scopes like variables/arguments/flash
etc... to some text file log using CFFILE to inspect what is in
them.



Also, have you tried short hand syntax for the argument like
#supplierid#? Or what about the #flash.supplierid# (not sure if
that is available via CFC but only CFM)?



If you are stuck then can you email me your flex code and cfc
to pfarland@adobe.com?

Avatar

Level 3
I got your sample to work.



A few things to mention after looking at the full version of
your code - note that to call a RemoteObject method that has
predefined MXML arguments then you would call it like this:



qResult.Inventory.send();



If you wanted to programmatically call it with arguments from
ActionScript, you'd call it like this:



qResult.Inventory(SupplierId, BrandId);



But the real problem was that you're calling the RemoteObject
method in the initialize property of a data grid - not only is this
unconventional, it won't work as you must wait until later to
access the Application.application scope. There is a more complex
set of reasons I won't go into here, but in general when working
with data or programmatic interactivity I suggest waiting for
creationComplete on the top level Application to be fired before
making any requests.