Our Blog

In the Introduction to Flash Remoting post, I explained how to connect to a Flash Remoting gateway. I believe that the most difficult part when using Remoting, however, is knowing how to manage the transfer of data from and to the server. This transfer happens when Flash makes a call to a service and sends parameters, and when the server sends a response (not a void function). I will first briefly explain how to send and receive any type of data and then go through all the data types available and show you how to handle them.

Sending data to the server

The simplest method to send parameters to a CFC function is by sending them in order, separated by commas inside the call parenthesis.
If we have the following CFC function:

<cffunction name="addCartItem" access="remote" returntype="boolean">
   <cfargument name="product_id" type="numeric" required="true">
   <cfargument name="quantity" type="numeric" required="false">
   <cfargument name="price" type="numeric" required="false">

   <!--- Do something--->
      
   <cfreturn true />
</cffunction>

We would call it by (get the data from some control, not hard coded like in this example):

var product_id = 462;
var quantity = 1;
var price = 10.50;

myService.addCartItem(product_id, quantity, price);

//or simply


myService.addCartItem(462, 1, 10.50);

But when our function requires a lot of parameters, this becomes tedious and error prone, since it’s very easy to mistakenly change the order of the parameters. A better way to send a lot of parameters is by sending an object (like an structure or hashmap) with key-value pairs that match our cfargument names:

var myArguments = {}; //or new Object();

myArguments.product_id = 462;
myArguments.quantity = 1;
myArguments.price = 10.50;

myService.addCartItem(myArguments);

//we could also use the abbreviated version:

myService.addCartItem({product_id: 462, quantity: 1, price: 10.50 });

Even another method is by using an “associative array” (very similar to the object method, but creating an array instead):

var myArguments = []; //or new Array();

myArguments["product_id"] = 462;
myArguments["quantity"] = 1;
myArguments["price"] = 10.50;

myService.addCartItem(myArguments);

Sending data to Flash

There is no trick here. To send data back to Flash, just use the cfreturn tag: <cfreturn myData />

Remember that the type of the data that you are sending to Flash must match the data type specified in the returnType attribute of the cffunction tag.

We access this data in our handler functions. If we use the Service object (see previous post), specifying the handler function as

new RelayResponder(this, "onCallReceived", "onFault");

we will get the results in our onCallReceived function, and the data will be inside the ResultEvent object in the property “result”.

function onCallReceived ( re:ResultEvent ):Void {
   var myData = re.result ;
}

If we are using the old method, then the data is directly in the “results” object

responseHandler.onResult = function(results: Object ):Void {
   //use the results

}

In that parameter, which we just called “results”, we receive whatever was sent by the server. If it was a string, for example, we will use it directly: myInput.text = results. Note that we can name this parameter however we want, it doesn’t have to be called “results” (same for the ResultEvent parameter in the Service example)

Strings and numbers

Strings and numbers are the easiest data types to use, as they are natively handled in Flash and CF. You can send data coming from a text input: myInput.text or anything that can be converted to a String by using the toString() function.

Numbers are a little more difficult just because CF is not strictly typed and Flash is. Sending numbers from Flash will always work, even if we send them as strings, as CF will be able to convert them, unless of course, you send other characters besides numbers in the string.

From our previous example, the first argument is numeric:

<cfargument name="product_id" type="numeric" required="true">

We can supply that argument by:

myService.addCartItem(3);

//Or


myService.addCartItem("3"); //not the best method

You can always replace that with a variable:

myService.addCartItem(productInput.text);

Returning a number is straight forward if we set the returnType of the function as numeric:

<cffunction name="getFavoriteNumber" access="remote" returntype="numeric">
   <cfset var myFavoriteNumber = 3 />
   <cfreturn myFavoriteNumber />
</cffunction>

You can even return it as a string <cfreturn “3”/> and it will still work. If you do not specify the returnType or you specify it as “any” (not recommended), it will be received as a string, not as a number. To convert it to a number, use the val() function:. We should always specify the returnType so this method shouldn’t be needed. There are times, however, when we do need it, even if we specify a data type. That is the case when we want to return a structure or array with numeric values. If we don’t use the val() trick, all the values will be strings, not numbers.

Boolean values

These behave in the same way as the numbers: from Flash to CF, anything goes, but from CF to Flash, they are all strings unless otherwise specified in the returnType attribute. Therefore, it is important to specify the returnType to boolean in our CFC function.

You can send any of these to a CF boolean argument (<cfargument name="active" type="boolean" required="true">)

myService.myFunction(true); //or false

myService.myFunction("yes"); //or "no"
myService.myFunction("true"); //or "false"

myService.myFunction(1); //or 0. For true, any non-zero value will do

All those will be accepted as boolean values by the function, and the argument can be used in boolean expressions as in , but only a true/false will be a real Boolean, all others will maintain their original value (so we will see a number or the string sent if we output them).

The same guidelines that I gave for numbers work for Booleans: always specify the returnType to boolean. But what happens if we want to set a boolean in an array and send that to Flash? We have a problem. They will be just strings, which means they will always evaluate to true when used in an expression: if (myReturnedValue) , which makes it a bug difficult to find.

So how do we ensure that Flash receives a boolean? Macromedia documentation says that we can send a 0/1, but that has never worked for me. The only way I found to make sure I am returning a boolean (if I am not returning the boolean directly so that I can specify the returnType), is to use the javacast function:

<cfset myBoolean = javacast("boolean",false) />

Arrays

Arrays can be sent either way without any problems. CF will receive an array in an arguments like:

<cfargument name="products" required="false" type="array"/>

The array can come from many different sources, such as a control’s dataprovider. It can also be created:

var myArray = [1,2,3];
myService.addCartProducts(myArray);

The arrays can also contain complex objects inside that follow all the other rules discussed here.

If we want to return an array from ColdFusion, we can set the returnType attribute to array:

<cffunction name="getProducts" access="remote" returntype="array">
   <cfset var products = arraynew(1)/>
   <cfset products [1] = "Product 1" />
   <cfset products [2] = "Product 2" />

   <cfreturn products />
</cffunction>

When we receive that on the Flash end, we just must remember that Flash array indices start at 0:

responseHandler.onResult = function( results: Object ):Void {
   myInput.text = results[0];

   //or loop over all the items received

   for (var i = 0; i < results.length; i++){
      //do something with the results[i] element

   }
}

Structures and objects

ActionScript associative arrays and simple objects can be sent to CF and they will be received as key-value structures. If we have an argument type struct in our CFC function:

<cfargument name="product" required="false" type="struct"/>

we use the same technique as when passing many arguments in one object or array:

var cartItem = {}; //or new Object();

cartItem.product_id = 462;
cartItem.quantity = 1;
cartItem.price = 10.50;

Or
var cartItem = []; //or new Array();

cartItem ["product_id"] = 462;
cartItem ["quantity"] = 1;
cartItem ["price"] = 10.50;

So what’s the difference?
The main difference is that it cannot be the only argument supplied to the function. If we pass that as the sole argument it will be interpreted as the arguments coming as key-value pairs (the shortcut to send many arguments at once). That means that the function must have other arguments we need to supply, so that the struct is not the only one:

myService.addCartItem(cartItem,customerId);

Or just send a bogus second argument to fool the gateway:

myService.addCartItem(cartItem,"");

We can then access this structure from ColdFusion as:

arguments.product.product_id

The other way around should be simple, but it does have some caveats due to the case-sensitive nature of Flash. In ColdFusion there are basically two way of creating and populating an structure:

Method A:

<cfset myStruct = structnew()/>
<cfset myStruct.product_id = 1 />

Method B:

<cfset myStruct = structnew()/>
<cfset myStruct["product_id"] = 1 />

When these two structures are used within CF, there is no difference between them, because CF is case-insensitive. If we send that to Flash:

<cfreturn myStruct />

it will receive different structures depending on what method was used to create them. With method A, it will receive results.PRODUCT_ID or results["PRODUCT_ID"], while if method B was used, it will receive results.product_id or results["product_id"] (what we most likely intended and expect).

It’s interesting to note that if you send a component instance to Flash, it will receive only the public properties (defined by this.myProperty), but no matter how we defined them (even by this["myProperty"]), they will always be upper case.

RecordSets and queries

RecordSets are handy complex objects that can carry a lot of data, which we can manipulate, sort and show in controls such as data grids. But you may be wondering what is a RecordSet beginning with. In ColdFusion terms, a RecordSet is what a query becomes when it reaches Flash. It contains the names of the columns and an array of records. It has several functions we can use such as getItemAt() or getColumnNames(). Going over all the features of a RecordSet is beyond this article.

RecordSet can only go one way, from the server to Flash. In ColdFusion, we just send a plain query.

<cffunction name="getProducts" access="remote" returntype="query">
   <cfset var products = "" />
   <cfquery name="products" datasource="MyDataSource">
      SELECT *
      FROM product
   </cfquery>

   <cfreturn products />
</cffunction>

I hope this overview helps you understanding how to use Remoting in the different scenarios that you may encounter. If you have any question, fell free to post it in the comments.

Laura

Laura

46 Comments

  1. PaulH
    another great posting. thanks a lot. of course this will generate the usual questions ;-)

    syntax like this:

    var addressArgs={
       address:address.text,
       city:city.text,
       state:state.selectedItem.data,
       zipcode:zipcode.text
    };

    doesn't seem to be recognized by the CFC as an argument. always seem to have to deal w/these in the CFC using Flash.Params. any idea what i'm doing wrong?

    thanks again. i love reading these things.
  2. Laura
    Paul,
    Are you trying to receive that as an struct argument?
    <cfargument name="address" type="struct"/>

    or you have individual arguments for each (address, city, etc)?
  3. Neil Bailey
    Laura,

    Welcome back! I was actually starting to go into withdrawal :-)

    Yet another great posting. Thanks!
  4. PaulH
    as a single argument. i guess i've missed the boat again. what should it be?
  5. Laura
    When you pass a single argument, and it is a struct/obj, the gateway interprets it as an argument collection, so your function is receiving 4 different arguments named address, city, state and zipcode.

    To tell it to treat it as a structure, you must have another parameters in your function call, even if those do not exist in your cffunction (just because we do not have overloading in CF) and you will be receiving an unnamed argument, so you can do:
    yourFunction(addressArgs,"");
  6. PaulH
    thanks. i get it now, though using a dummy argument like that doesn't sit very well w/me. i guess i'll swap to using the separate named arguments.
  7. Laura
    I know, it is sort of a workaround.
    You can also encapsulate it in another object:

    yourFunction({address:addressArgs});
  8. Steve Walker
    Laura,

    Thank you very much. This was so clear. Any chance you can add to this with an example of how to pass a variable from each of the Flash Form controls?
  9. Rick
    I know it wasn't covered in the tutorial so could somebody provide even just a brief example of how you would output a query returned from a ColdFusion cfc inside of a respondeHandler function? I'm still new to ActionScript and Remoting and not sure how to do that.
  10. Brian Sloan

    Brian Sloan

    Laura,

    I am using cflogin and have it timeout after 20 minutes. In my application cfc files it checks to see if the user is logged in and if not makes them login and then continues the operation. Now that I am using remoting, if the users session timesout and they click on something that requires the remoting I get an error &quot;Error while calling cfc:event handler exception.&quot; Is there a good way to catch this and popup a login screen or something? -- This would be a great post.

    Thanks,
    Brian
  11. Todd
    I'm curious about additional techniques to handle errors while calling a cfc. I have the standard &quot;Error while calling cfc&quot; alert, however this doesn't always tell the user too much info - and - more importantly, it doesn't alert me as the developer that an error occured. Any ideas on how to set up an error log or get an automated email? I'd love a dump of the form - but I'm sure that's probably asking too much. :)

    Been a while since the last post on asfusion...(grins and rubs hands together in anticipation of the next post)
  12. dickbob

    dickbob

    Does the instance of the object created by Flash, by...

    custService = new Service(&quot;http://localhost/flashservices/gateway&quot;, null, &quot;customerData&quot;, null, null);

    ...exist outside the Flash &quot;session&quot;?

    I'm trying to send some data out from Flash and want it to persist in a cfc object for a later getURL call to a .cfm page to be able to read and process.

    The full requirement is for Flash to gather the data and then pass it out to CF to display in a popup window as a pdf.
  13. Todd
    Laura,

    How would I pass the entire contents of a cfgrid to the cfc?
  14. Laura
    Steve,
    You mean passing all the form controls in one big variable?

    Rick,
    You can output the query in a cfgrid, check
    http://www.asfusion.com/blog/entry/populating-a-cfgrid-with-flash-remoting

    Brian,
    Yes, that would be a great post :)
    I will try to write it when I get a chance. I think the best would be to check for a valid session in the remoting function (or call one that takes care of sessions) and if they user is not logged in, throw an exception you can catch in Flash. How you handle that would be up to you, from redirecting to a login screen or somehow show a login form without refreshing the page.

    Todd,
    That would be a great post too. Many people has asked me how to debug remoting. There are some errors you can catch and send an email or log it. Others it is more difficult.

    dickbob,
    No, each time you call a service, a new instance of that component is created. You can, however, reference a component residing in memory by calling it from the service component.

    Todd,
    I wouldn't recommend to pass the entire datagrid back to cf if the data is large. But if you really want to, you can send myGrid.dataProvider (if you loaded the grid normally, or used remoting but set the data provider as myGrid.dataProvider = results.items), otherwise use myGrid.dataProvider.items
  15. Thomas

    Thomas

    Hi Lara,
    Well I'm new, the very definition of a newb i guess. Anyway, I am able to get all hooked up to my cfc. It's returning an array.

    If I set it to a text field, like in the Flash help example, it will display all four items from the array. EG

    function randomPicture_result(result:ResultEvent) {
    messageDisplay.text = result.result[0];
    }

    However, what I need to do is set each value from the array to a variable. I'm gonna use each variable in an loader component as the end of a path, to display four images,

    i just cant seem to figure out how to assign each value of the array to the variable i need.

    i apologize to the flash vets for missing what must be obvious
  16. Laura
    Thomas,
    I don't know if I understand correctly, but anyway, here is my answer.
    It seems that you are returning a structure, with an element called result which is an array.
    If so, then when you do result.result[0] you shouldn't get the 4 array elements, but only the first. If you are getting the four elements, it means the element result has an array, in which the first element is another array.

    It's difficult to help you without looking at your remoting component.
  17. Jason
    Dear Laura,
    I got stuck playing the remoting with structure

    var sessionArgs = {};
    sessionArgs.dsn = "#session.dsn#";
    myService.getTest(sessionArgs,"");

    Then I call it in my cfc
    <cfargument name="mySession" required="false" type="struct" />

    #arguments.mySession.dsn#

    why mySession.dsn is undefined in arguments?
    Anything wrong? thanks
  18. Thomas
    Lara, here's the component:

    <cfcomponent>


       <cffunction name="randomPicture" output="true" access="remote" returntype="array" >

       <cfset Peopledirect = ExpandPath("/images/random_people/")>

       <cfdirectory directory="#Peopledirect#" action="list" name="people" filter="*.jpg">

    <cfset lstPeopleFileNames = valuelist(people.name)>
    <cfif people.recordcount lt 4 >
            not enough images to produce banner
    <cfelse>
            <cfset lstPeople= ListGetAt(lstPeopleFileNames,RandRange(1, people.recordcount))>

           
            <cfloop condition="listLen(lstPeople) lt 4">
                    <cfset temp = ListGetAt(lstPeopleFileNames,RandRange(1, people.recordcount))>
                    <cfif listfind(lstPeople,temp) eq 0>
                            <cfset lstPeople = listAppend(lstPeople,temp)>
                    </cfif>
            </cfloop>
           
    </cfif>


       <cfset randomPics = ListToArray(lstPeople)>
    <!----
       <cfset randomPics = ArrayNew(1)>
       <cfset randomPics[1] = "#ListGetAt(lstPeople,1)#" >
       <cfset randomPics[2] = "#ListGetAt(lstPeople,2)#" >
       <cfset randomPics[3] = "#ListGetAt(lstPeople,3)#" >
       <cfset randomPics[4] = "#ListGetAt(lstPeople,4)#" > ---->
       
    <!----       <cfset randomPics = "Hello World"> ---->

          
          <cfreturn randomPics>
       </cffunction>
    </cfcomponent>


    Here's my full actionscript: (as you can see, i dont set the values of the array to variables and use the load, i just put the loads into the responder results. Also, im getting this weird thing where upon every fourth or fifth reload i randomly lose a picture. dif pics are lost.)



    import mx.remoting.Service;
    import mx.services.Log;
    import mx.rpc.RelayResponder;
    import mx.remoting.PendingCall;
    import mx.rpc.ResultEvent;

    // connect to service and create service object

    var CFCService:Service = new Service (
       "http://www.wordablaze.net/flashservices/gateway",
       new Log(),
       "cfcs.random_image",
       null,
       null );
                               
                               
    // call the service

    var pc:PendingCall= CFCService.randomPicture();

    //get the result from from the service

    pc.responder = new RelayResponder(this, "randomPicture_result");

    //feed the result into the loaders

    function randomPicture_result(re:ResultEvent)
    {
    image_loader_two.contentPath = "http://www.wordablaze.net/images/random_people/" + re.result[0];
    image_loader_three.contentPath = "http://www.wordablaze.net/images/random_people/" + re.result[1];
    image_loader_four.contentPath = "http://www.wordablaze.net/images/random_people/" + re.result[2];
    image_loader_five.contentPath = "http://www.wordablaze.net/images/random_people/" + re.result[3];
    }



    stop();
  19. Neil Huyton

    Neil Huyton

    Does anyone know if it's possible to have an interaction between a flash movie and a cfform that are on the same page. Basically we want it so that when an item in the flash movie is clicked, the corresponding items in the flash form is selected.
    We've tried embedding the swf in the cfform but this causes it to run real slow.
    We can call a cfc from the flash movie but how can it be done so that it's not the caller (flash movie) that gets the results, but the cfform.

    I'm pretty sure this can't be done, but I just thought I'd see if anybody has done this.

    Thanks.
  20. Fritz Dimmel
    Hello!
    I just want to say thank you for your great site. This posting is one of many which helps me a lot in the last weeks!
    Keep up this good work!

    Fritz
  21. Yogesh Mahadnac

    Yogesh Mahadnac

    Hi!

    First of all, thanks for all the information present on this website, it's truly of a great help! :-)

    Ok, now, I've got 2 questions. Actually I've been trying to find the answer on Macromedia's ColdFusion forum but nobody has ever been able to answer me. I hope i'll have better luck here! So, please bear with me till the end... :-)

    Here is the situation:

    If my cffunction needs a lot of parameters from flash, the best thing would be to create an object (or structure as it is more commonly called in ColdFusion) in flash form actionscript, right? I also totally agree with that.

    I quote:

    var myArguments = {}; //or new Object();
    myArguments.product_id = 462;
    myArguments.quantity = 1;
    myArguments.price = 10.50;

    myService.addCartItem(myArguments);

    But then, why is it that in my cffunction I cannot create a cfargument called e.g. myFlashData of type struct? I've noticed that I need to create a separate cfargument for each of the parameters of myArguments. i.e.
    Instead of
    <cfargument name="myFlashData" type="struct" required="yes">

    I need to do
    <cfargument name="id" type="numeric" required="yes">
    <cfargument name="name" type="string" required="yes">
    etc...

    This is somehow weird, because I've also been using Actionscript in Flash MX 2004 and I've always created only 1 cfargument of type struct in my CFC and then I reference each key e.g. #arguments.myFlashData.id#, '#arguments.myFlashData.name#' etc in my cfquery.


    2.
    What I've also been doing every time in Flash MX 2004 Actionscript is to send the whole contents of my datagrid to my CFC to either add or update. But unfortunately I haven't been able to reproduce the same using Flash Forms.

    E.g. If I have a button called Update, on the onclick event, I usually do

    on(click) {

    var myArr = new Array();
    for(var i = 0; i < myGrid.length; i++)
    {
    var myData = new Array();
    myData["id"] = myGrid.getItemAt(i).id;
    myData["name"] = myGrid.getItemAt(i).name;
    myData["addr"] = myGrid.getItemAt(i).addr;
    myArr[i] = myData;
    }
    //and then I submit myArr to my CFC
    myService.updateRecords(myArr);

    //i'm sending the whole grid data as an array of structures to my CFC
    }

    And then in my CFC, I have my function called updateRecords

    <cffunction name="updateRecords" access="remote" returntype="void">
    <cfargument name="myArr" type="array" required="yes">

    <cfloop index="i" from="1" to="#arrayLen(arguments.myArr)#">

    <cfquery datasource="#application.myDsn#">
    update myTable
    set
    name = '#arguments.myArr[i].name#',
    addr = '#arguments.myArr[i].addr#'
    where id = #arguments.myArr[i].id#
    </cfquery>


    </cfloop>
    </cffunction>

    Is there an equivalent or a way to possibly do this using Flash Forms? If yes, how do you create the array of structures in Flash forms actionscript? And how do you define your arguments in CFC?

    Please advise on these 2 issues.

    Thanks and regards
  22. Neo
    Hi,
    I have a question, How to refresh a cfgrid in a cffomr after update data from a cfform + remoting (cfc) without refreshing the browser window ?

    thks
    Neo
  23. Yogesh Mahadnac

    Yogesh Mahadnac

    Hi Neo,

    All you need to do is to call the function to populate your data grid immediately after you call the function to update the data.

    E.g.

    <!--- Make a call to add record to db --->
    if( mx.validators.Validator.isStructureValid(this, 'myForm') ){
       
       <!--- Set busy cursor --->
       mx.managers.CursorManager.setBusyCursor();
       
       myForm.myGlobalObjects.adjustment.createAndUpdate(myData);
    }

    <!--- Make a call to get adjustments for the selected element --->
    myForm.myGlobalObjects.adjustment.getAdjustment(currency_cb.selectedItem.data);


    In my function setUpRemoting, I have the following code:

    <!--- Create default reponse handler objects --->
    var responseHandler:Object = {};

    <!--- put controls in the responseHandler's scope --->
    var myGrid:mx.controls.DataGrid = myGrid;


    <!--- handle search by default onResult function --->
    responseHandler.onResult = function( results: Object ):Void {
       if(results.length != 0)
       {
          myGrid.dataProvider = results;
       }
       else
       {
          alert("No record found for the broker selected!");
          myGrid.removeAll();
       }
       mx.managers.CursorManager.removeBusyCursor();
    }


    So every time I update the data grid or add new items to it, I immediately call the function getAdjustment to populate myGrid with updated records.

    Hope this helps.

    Regards,
  24. JohnDoe

    I am having trouble getting access to data returned from a flash remoting call to a coldfusion query. The easy way is to use a dataGrid and set its dataProvider = result, but I don't need the dataGrid for my application.

    Is there any way to get access to the raw results (in Flash I would have pumped it into a dataSet and then used it from there) or do I have to use an invisible DataGrid?
  25. Neo
    Thank Yogesh for your answer.

    But I have another problem.
    My problem is that when I've made a datagrid refresh when I'm upload a image that with the same name in the dababase (ex: in my database the inital image name is IMAGE1.JPG) if I upload an image with the same name, the refresh grid not work with the image field. But if I upload an image with a different name that thios is recorded in database, the refresh datagrid fucntion work fine...

    So have you a solution to refresh the grid with image field even though the image name is the same already present in database field ?

    Thks
  26. Jimmy
    Hi Laura,

    I'm trying to do a cfgrid update based on a start date and end date. These 2 dates are selected by the user and the cfgrid would display the moment they start selecting. How would I pass the 2 dates and return the data back in the grid?
  27. Luciano Gonzales
    I have a flash movie that performs 1 data request via flash remoting (successfully). However, when I click a button to do a second data request the server never returns the data (a simple string) nor does it send an error. If I refresh the page (Ctrl-F5) and do it again, everything is OK. I've taken a very complicated Flash Movie and reduced it to a very simple movie to simplify the diagnostics. I've had no luck. Any ideas ??
  28. Laura
    Luciano,
    How do you know the server is not called?
    I would use Fiddler or Live HTTP Headers (or any other http debugger) to see if the server gets call.
  29. Macd
    Having trouble getting Flash Remoting to return the results after querying the database. I have tried .cfc and .asr methods. For some reason it will not return the results. What am I doing wrong. I know its simple for sure.

    Here is a portion of the code:

    <u>component called accessData.cfc</u>
    <cfcomponent>
       <cffunction name="checkLogin" displayName="Checking user login" access="remote" returntype="query">
       <cfargument name="username" required="yes" type="any">
       <cfargument name="password" required="yes" type="any">
       <cfset var rscheckLogin = " ">
       <cfquery name="rscheckLogin" datasource="dataset">
          select * from users where username = '#username#' and
           password = '#password#'
          
    </cfquery>
          <cfreturn rscheckLogin>
       </cffunction>   
    </cfcomponent>

    <u>Actionscript to call this cfc</u>

    if (inited == null) {   
       inited = true;
       NetServices.setDefaultGatewayUrl("http://the domain/flashservices/gateway");
       gatewayConnection = NetServices.createGatewayConnection();   
       loginService = gatewayConnection.getService("accessData", this);   
    }

    loginService.checkLogin(username_ti.text, password_ti.text);

    here is the result code:

    function checkLogin_result(rslogin) {
       trace('CheckLogin result');
       if (rslogin.length > 0) {
          gotoAndStop("ondemand");
       } else {
          status_lbl.text = "<font color=\"#EFDFDC\">invalid user name / password.</font>";
          // set the form focus to the username_ti TextInput instance and select the existing text.
          Selection.setFocus(username_ti);
          Selection.setSelection(0, username_ti.text.length);
       }
    }
  30. Lesley
    I keep getting this error and I can't find what is the problem. The statement 'Public' is incomplete. Can anyone advise?
  31. Steve
    I tried passing in a grid to a cfc using the suggestion to Todd above. I can't get it to work.

    I get an error when I try to do it that says: The argument DATAGRIDDATA passed to function testGridToCFC() is not of type Struct. I also tried Array, Query, object, and others all with the same result (naming the type I used of course).
    I tried myGrid.dataProvider and myGrid.dataProvider.items all with the same result.

    What I'm trying to do is populate a grid through remoting (not a large grid), let the user edit it, and then submit the changes back to the cfc.

    Any ideas?
  32. Steve
    Well, I couldn't do what I wanted with the grid information, but after reading (and reading and reading) the Flex 1.5 documentation, I created a function that coverts the grid object into a multidimensional array. Then I pass that array to my cfc. Worked like a charm.

    I'll post the function to my blog a little later.
  33. Joel
    Does this all work with Flex 3 and Action Script 3?
  34. Laura
    Joel,
    Most of it will work and the idea is the same, although you might need some updates to the syntax. What it won't work is the section "Sending data to Flash" as that has changed.
  35. Darren
    i've go a cf query coming into flash via remoting and need to turn it into an array like this


    var productData:Array = [
                       {title:"Brindley Place 1", fullsize:"dtl_Central_Square_1.jpg", thumb:"thmb_Central_Square_1.jpg", view:"view_Central_Square_1.jpg", zip:"zip_Central_Square_1.zip", description: "One of the UK’s largest new city centre squares", collectionID: 1}];

    i can see the array in a trace command but can't seem to get at it, or moreover gid rid of all the other gubbins that gop with it, heres the trace:

    11/29 23:42:59 [INFO] : Invoking argent on cfdocs.argent.code.gallery.remoteservices
    11/29 23:43:0 [INFO] : cfdocs.argent.code.gallery.remoteservices.argent() returned {_items: [{__ID__: 0,
    collectionID: 1,
    description: "One of the UK?s largest new city centre squares",
    fullsize: "dtl_Central_Square_1.jpg",
    thumb: "thmb_Central_Square_1.jpg",
    title: "Brindley PLace",
    view: "view_Central_Square1.jpg"},
    {__ID__: 1,
    collectionID: 1,
    description: "One of the UK?s largest new city centre squares",
    fullsize: "dtl_Central_Square_2.jpg",
    thumb: "thmb_Central_Square_2.jpg",
    title: "Brindley PLace",
    view: "view_Central_Square2.jpg"}],
    gateway_conn: {__originalUrl: "http://192.168.1.250:8500/flashservices/gateway",
    __urlSuffix: "?;jsessionid=a4301a3220aa75782c28",
    contentType: "application/x-fcs"},
    logger: {level: 0, name: ""},
    mRecordsAvailable: 2,
    mTitles: ["collectionID", "fullsize", "thumb", "view", "title", "description"],
    serverInfo: null,
    uniqueID: 2}
    can't i just grab the array out, i don't need anything else
  36. Laura
    Darren,
    When you send a query via remoting, you receive a RecordSet object. It contains a variable, "items" that is an array with the data.
  37. Matt
    Hello to all, and thank you for the great information on this site. I am attempting to implement my first Flash Remoting project, in conjunction with a ColdFusion back-end. My Flash file is referencing a 'helloWorld2.cfm' file located in the 'remoteservices' folder underneath my ColdFusion webroot directory location. I am populating a structure with two values, which I am then sending to Flash. Everything works great as long as I specify the values for the structure from within the 'helloWorld2.cfm' page. But for my project to work correctly, I need to populate the structure with two session variables - 'session.level' and 'session.minutes'. These session variables in, in fact, populated, and I can even use a <cfdump> tag to output the structure to the screen, which shows the correct values. But if I attempt to populate the structure in 'helloWorld2.cfm' with the session variables that are defined elsewhere, my Flash movie plays with the text 'undefined' where the value should be.

    Here is the code that works in 'helloWorld2.cfm':

    <cfset session.level = 3>
    <cfset session.minutes = 8>

    <cfset tempStruct = StructNew()>
    <cfset tempStruct.level = session.level>
    <cfset tempStruct.minutes = session.minutes>
    <cfdump var="#tempStruct#">
    <cfset flash.result = tempStruct>

    If I remove those first two lines of code, so that 'session.level' and 'session.minutes' are not defined in 'helloWorld2.cfm' but rather in my main ColdFusion page which contains the Flash movie and populates those values correctly, I get the 'undefined' message in the Flash movie where 'level' and 'minutes' should appear with the data.

    I hope this makes sense. Any assistance you can provide is greatly appreciated. Thanks for your help!
  38. JoelJ
    I have a standard session based shopping cart structure. I manage the items in the cart structure via a cfc. I'm calling an add2cart function in that cfc from flash and from coldfusion. When I invoke it via coldfusion, I see the item get added to the structure. When I invoke it from flash via remoting, I can see that the function executes, but the item is not added to the session.cart. Is this because remoting opens another session with coldfusion seperate from the session that the flash app itself is running in? Can someone help me understand this behavior and give a suggestion to how I might work this?

    Thank You,

    Joel
  39. Luciano
    How are you adding it to the session variable via the flash module, i.e., how are you managing session variables through the actionscript?
  40. JoelJ
    I'm not adding to the session variable via actionscript at all. I'm simply handing the value in flash to a cfc which calls a session object and appends the value from flash's call of the cfc to that session object.
  41. vinod
    when u access database value through remoting the below error show in output. Can u plz help me on thi error where we kept the slideShow folder of datasource file.

    "Data source slideShow could not be found."
  42. Karon E

    Karon E

    I am trying to update a combobox by calling a cfc file on the Change event of another combo box using an Actionscript function. I need to know how to get to update the combobox with the data returned. Here is the function code I have thus far.

    <cfformitem type="script">
    function GetMasterList(){
          var responseHandler = {};
          responseHandler.onResult = function( results: Object ):Void {
          }
          responseHandler.onStatus = function( stat: Object ):Void {
          }
          
          mx.remoting.NetServices.setDefaultGatewayUrl("http://ispdev.wff.nasa.gov/flashservices/gateway/");
          var connection:mx.remoting.Connection = mx.remoting.NetServices.createGatewayConnection();
           var myService:mx.remoting.NetServiceProxy = connection.getService("isp_cfcomponents.GetMaster", responseHandler);
          myService.GetMaster(cmbPlanType.value, 1);
    {
    </cfformitem>
  43. Steve
    I'm very new to Flash Remoting and I'm stuck on what is likely a very simple solution.

    This is a test project that sends a barcode id from one SWF text field to a CFC that queries the database and returns a first name and last name to another SWF text field.

    I've looked at a multitude of remoting examples and can't figure out how to send and receive the data (or access it).

    ActionScript Code
    import mx.remoting.Service;
    import mx.rpc.RelayResponder;
    import mx.rpc.ResultEvent;
    import mx.remoting.PendingCall;

    if (isGatewayOpen == null) {

    isGatewayOpen = true;
    // Make the Gateway connection

    NetServices.setDefaultGatewayUrl("http://127.0.0.1:8501/flashservices/gateway");
    gatewayConnnection = NetServices.createGatewayConnection();
    checkIn = gatewayConnnection.getService("testing.components.receive_send", this);
    trace("Connected");
    }
    new RelayResponder(this._parent, "onCallReceived", "onFault");
    //results in our onCallReceived function

    //data will be inside the ResultEvent object in the property “result”.

    trace("RelayResponder connected. Data in OnCallReceived function");

    function onCallReceived ( re:ResultEvent ):Void {
    var myData = re.result ;
    }

    callButton.onPress = function(){
    //want to set the text field to the returned data from CFC
       name.text =

    }

    stop()


    I'm confident that the CFC is working. I tested with a CFM page. Here's the CFC code

    <cffunction name="getDelegate" access="public" returnType="query">

          <cfargument name="barcode" type="string">
          <CFQUERY NAME="getDelegate" Datasource="BDM">
             SELECT concat(ucase(left(d_fname,1)),substring(d_fname,2)) as "fname",
    concat(ucase(left(d_lname,1)),substring(d_lname,2)) as "lname"
             FROM delegates
             WHERE d_barcode = 13564358456
          </CFQUERY>
          <cfreturn getDelegate>
       </cffunction>
    </cfcomponent>


    Any help would be appreciated.

    Thanks!
    Steve
  44. Herbert

    Herbert

    hi,
    how can i pass ALL the form variables including grid-data to a remoting-cfc in one big structure? (like the form structure in cf)

    regards
    herbert
  45. Herbert

    Herbert

    hi it's me again.

    how can i get a meaningful structure from cfgrid data in my cfc?

    how can i get this cfgid-values, sent with flashremoting
    var myform= myform;
    myService.submitform(myform);

    back to a "real" structure?

    __CFGRID__EDIT__=2nameYageY3UAlliciaAlicia3323UAllanAlan3430UAdamssAdams2423

    thanks in advance
    herbert