8 Replies Latest reply on Feb 5, 2010 8:53 AM by Radhakrishna Bhat

    Passing a Structure from CF to Flex via remote services

    ZephanRC

      I am using CF9 and Flash Builder 4 Beta.  I am trying to pass a Structure from CF to Flex in order to pass both a "Success" booleen and "Message" along with an array of data to Flex Builder via remote data services.

       

      This is the applicable part of my .cfc file:

       

      <cfcomponent

       

      output="false">

       

      <cffunction name="getOutages" access="remote" returntype="Struct" >

      <

      cfquery name="outagesRS" datasource="outages">

       

      SELECT *

       

      FROM outageList

       

      ORDER BY ID

       

      </cfquery>

       

       

      <cf_QueryToArray Query="#outagesRS#" Variable=outagesArray>

       

       

      <cfset ans = StructNew()>

       

      <cfset ans.success = true>

       

      <cfset ans.msg = "Retrieved all outages">

       

      <cfset ans.data = #outagesArray#>

       

       

      <cfreturn #ans#>

       

      </cffunction>

       

      I created a remote data service to the .cfc file and I get a valid response when I test the service...

       

      test.JPG

      Here is my Flex Application "outagesApp.mxml"

       

      <?xml version="1.0" encoding="utf-8"?>

      <s:Application

       

      xmlns:fx="http://ns.adobe.com/mxml/2009"

      xmlns:s="

      library://ns.adobe.com/flex/spark"

      xmlns:mx="

      library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768" xmlns:outagesservice="services.outagesservice.*">

       

      <fx:Script>

      <![CDATA[

       

      import mx.events.FlexEvent;

       

      import mx.controls.Alert;

       

       

      protected function dataGrid_creationCompleteHandler(event:FlexEvent):void

      {

      getOutagesResult.token = outagesService.getOutages();

      }

       

      ]]>

       

      </fx:Script>

       

      <fx:Declarations>

       

      <s:CallResponder id="getOutagesResult"/>

       

      <outagesservice:OutagesService id="outagesService" fault="Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)" showBusyCursor="true"/>

       

      <!-- Place non-visual elements (e.g., services, value objects) here -->

       

      </fx:Declarations>

       

      <mx:DataGrid x="0" y="0" id="dataGrid" creationComplete="dataGrid_creationCompleteHandler(event)" dataProvider="{getOutagesResult.lastResult.DATA}">

       

      <mx:columns>

       

      <mx:DataGridColumn headerText="ID" dataField="id"/>

       

      </mx:columns>

       

      </mx:DataGrid>

      </s:Application>

       

      I am trying to display the fields contained in the "DATA" object in a DataGrid Object.  I tried changeing the data provider by adding ".DATA" on the end of the "lastResult", but with our without out that I get an empty data grid.  Is what I am trying to do possible?  What am I doing wrong?

        • 1. Re: Passing a Structure from CF to Flex via remote services
          SunilAdobe Adobe Employee

          You are doing it correctly.

           

          You might want to check this

          Since it’s a cfquery the outagesArray will be an array, so it might be one of the following or both

           

          1. Try using lower case for DATA

          2. Have you tried using test operation to see the actual result, if lastResult is an array then you might have to do lastResult[0].DATA

           

          Thanks

          -Sunil

          • 2. Re: Passing a Structure from CF to Flex via remote services
            ZephanRC Level 1

            I have used the "Test Operation" and as shown below, the result is an object with a MSG string, SUCCESS boolean, and DATA which is an array of objects/structues (ArrayCollection).  I have tried lowercase DATA in the DataGrid/DataProvider, but the "content assistant" actually sees the DATA array (as well as the MSG and SUCCESS) and automatically puts it in as upper case.  lastResult is not an array (it should be the entire structure below, DATA is an array of objects/stuctures), so lastResult[0] didn't help.  I have already tried lastResult.DATA[] and lastResult.DATA[0] with no success.  It appears that lastRessult.DATA is the correct syntax, and it complies, I just get a grid (single "ID" column) with no data in it (even though the "Test Operation" shows valid data in the DATA arrary).  Is the DataGrid object suppose to be able to take an "ArrayCollection"?  The examples that I have seen online seem to always have the service return a "query result set", but I would like to use the QueryToArray as I show in my .cfc and atually return the below structure with the MSG string and SUCCESS booleans along with the DATA ArrayCollection.

             

            test.JPG

            • 3. Re: Passing a Structure from CF to Flex via remote services
              ZephanRC Level 1

              I have also tried binding the data to a RichText component (see below).  Again things seem to compile just fine, but RichText box ends up empty.

               

              <s:RichText

               

              x="10" y="191" text="{getOutagesResult.lastResult.MSG}" width="248" id="richText"/>

               

              I just don't get it.  Even though the remote service (below) does not come up with the fault message and "Test Operation" shows data, no data shows up in the UI components???/

               

               

              <outagesservice:OutagesService id="outagesService" fault="Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)" showBusyCursor="true"/>

               

              I have even tried adding an intialization on application creation (see below).  Even though the DataGrid object already had an creationComplete event handler defined that should have populated the "getOutagesResult" CallResponder.

               

              <s:Application

               

               

              xmlns:fx="http://ns.adobe.com/mxml/2009"

              xmlns:s="

              library://ns.adobe.com/flex/spark"

              xmlns:mx="

              library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768" xmlns:outagesservice="services.outagesservice.*"

              creationComplete="initApp()"

              >

              .

              .

              .

              protected function initApp():void {

              getOutagesResult.token = outagesService.getOutages();

              }

               

              This is driving me nuts!

               

               

              • 4. Re: Passing a Structure from CF to Flex via remote services
                ashar2005 Level 1

                Sometimes addressing object elements as object["element"] works better than object.element.

                 

                Try using getOutagesResult.lastResult["DATA"]   and getOutagesResult.lastResult["MSG"]

                and see if that works.

                • 5. Re: Passing a Structure from CF to Flex via remote services
                  ashar2005 Level 1

                  I noticed a couple of other things....

                   

                  1.  A query result is a native data type to Flex, so your CF code does not need to use queryToArray

                      to cast the query variable to an array variable.   Just do this....

                     <cfset  ans.data = outagesRS /> 

                   

                  2.  Datagrids need to bind to ArrayCollections/Arrays.   Your displayed inspection of the DATA element

                       shows as it being typed Object and not an Arraycollection or Array.  

                      See if making the change above in #1 changes that DATA element inspection to being Arraycollection or Array

                      and makes it work.

                     

                     If it still doesn't work, try one of these :

                   

                     a)  I'm not sure if binding to a cast will work, but try binding to the variable cast.....  

                     { (getOutagesResult.lastResult["DATA"] as ArrayCollection) }

                   

                     and if that doesn't work...

                   

                     b) You may need to set a result handler for your service, and then in the result handler set

                     a local bindable variable.   In your script section    ....

                     [Bindable]

                     private var AC_Outages:ArrayCollection = new ArrayCollection();

                   

                     set your dataprovider to {AC_Outages}

                   

                     Then in your result handler ..

                   

                   

                     AC_Outages = getOutagesResult.lastResult["DATA"] as ArrayCollection;

                     AC_Outages.refresh();

                  • 6. Re: Passing a Structure from CF to Flex via remote services
                    ZephanRC Level 1

                    Thanks for the suggestions...  It may be a while before I can get back to this project and try your suggestions , but I will let you know.

                    • 7. Re: Passing a Structure from CF to Flex via remote services
                      SunilAdobe Adobe Employee

                      It might be because the returned value is not getting converted to the customdatatypeoutages type. I'm filing a bug for us to investigate.

                      https://bugs.adobe.com/jira/browse/FB-25799

                       

                      Thanks

                      -Sunil

                      • 8. Re: Passing a Structure from CF to Flex via remote services
                        Radhakrishna Bhat Level 3

                        Hello,

                         

                        I am able to see the data returned at runtime also including DATA[] property.  Also, you can directly assign "outagesRS" property to "ans.data". If you are still facing issues, please update the bug https://bugs.adobe.com/jira/browse/FB-25799 with your problems.

                         

                         

                        -Radhakrishna