8 Replies Latest reply on Jun 5, 2009 1:39 PM by Justin Schroeder

    Relating 2 tables with one List Control

    tstorb1 Level 1

      I am testing the new data services in FB4 with PHP.   I have created a simple List control that displays a mySQL list  -- which works fine.

       

      When I double click on an item in the list, I want to use it as the search index for a second table. I use the doubleclick event to make the call to search the second table.

       

      I set the dataprovider of the same List control to the new search result array returned from the second table.   This does not work.

       

      The Individual search code to each table work fine, but calling the second search in the doublclick event function does not.

       

      any examples would be appreciated.

        • 1. Re: Relating 2 tables with one List Control
          deepa subramaniam (adobe) Level 2

          Could I see some sample code of how you're calling the second search within the List's doubleclick event handler?

           

          Thanks,

          Deepa Subramaniam

          Flex Framework Engineer

          • 2. Re: Relating 2 tables with one List Control
            tstorb1 Level 1

            Thanks for your help.   My code is below:

             

            <?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" height="314" width="574" xmlns:categories="services.categories.*" xmlns:subcategories="services.subcategories.*">

            <fx:Script>

            <![CDATA[

            import mx.collections.ArrayCollection;

            import mx.events.FlexEvent;

            import mx.events.IndexChangedEvent;

            import com.adobe.serializers.utility.TypeUtility;

            import mx.controls.Alert;

             

             

            protected function connectToData(event:FlexEvent):void

            {

            getAllItemsResult.token = categories.getAllItems();

            }

             

             

            protected function list1_doubleClickHandler(event:MouseEvent):void

            {

            var item:* = category.dataProvider.getItemAt(category.selectedIndex);

            getAllItemsResult2.token = subcategories.getAllItems(item.id);

             

            category.dataProvider = TypeUtility.convertToCollection(getAllItemsResult2.lastResult);

            category.labelField = "name";

            }

            ]]>

            </fx:Script>

            <fx:Declarations>

            <s:CallResponder id="getAllItemsResult"/>

            <categories:Categories id="categories" destination="categories" endpoint="http://springblue/justin/flex/groupbrowser/bin-debug/gateway.php" fault="Alert.show(event.fault.faultString)" showBusyCursor="true" source="categories"/>

            <s:CallResponder id="getAllItemsResult2"/>

            <subcategories:Subcategories id="subcategories" destination="subcategories" endpoint="http://springblue/justin/flex/groupbrowser/bin-debug/gateway.php" fault="Alert.show(event.fault.faultString)" showBusyCursor="true" source="subcategories"/>

            </fx:Declarations>

            <s:List x="25" y="28" height="265" width="525" id="category" doubleClickEnabled="true" doubleClick="list1_doubleClickHandler(event)" creationComplete="connectToData(event)" dataProvider="{TypeUtility.convertToCollection(getAllItemsResult.lastResult)}" labelField="category_name" contentBackgroundColor="#E5E5E5"/>

             

            </s:Application>

            • 3. Re: Relating 2 tables with one List Control
              rfrishbe Level 3

              I can't comment too much about the example as a whole as I was missing several of the files for your project.  I did do a simple test around the double-click, and all seemed to work fine for me.  To debug your issue, I'd try to step in the debugger to figure out exactly what call is failing.

               

              -Ryan

               

              <?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">

               

              <fx:Script>
                  <![CDATA[
                      protected function list1_doubleClickHandler(event:MouseEvent):void
                      {
                          var item:* = category.dataProvider.getItemAt(category.selectedIndex);
                          trace(item);
                      }
                  ]]>
              </fx:Script>

               

              <s:List x="25" y="28" height="265" width="525" id="category" doubleClickEnabled="true" doubleClick="list1_doubleClickHandler(event)">
              <mx:ArrayList>
                  <fx:String>Hi1</fx:String>
                  <fx:String>Hi2</fx:String>
                  <fx:String>Hi3</fx:String>
                  <fx:String>Hi4</fx:String>
                  <fx:String>Hi5</fx:String>
                  <fx:String>Hi6</fx:String>
                  <fx:String>Hi7</fx:String>
              </mx:ArrayList>
              </s:List>

               

              </s:Application>

              1 person found this helpful
              • 4. Re: Relating 2 tables with one List Control
                Sreenivas R Adobe Employee

                The following code doesn't work

                 

                category.dataProvider = TypeUtility.convertToCollection(getAllItemsResult2.lastResult);

                 

                because the service call "subcategories.getAllItems" is made asynchronously. A result event is dispatched when the result has been obtained from the server.

                 

                If you move the assignment to the result event handler of the CallResonder as follows it should work.

                 

                <s:CallResponder id="getAllItemsResult2"  result="category.dataProvider = TypeUtility.convertToCollection(getAllItemsResult2.lastResult)"/>

                 

                -Sreenivas

                • 5. Re: Relating 2 tables with one List Control
                  Justin Schroeder

                  (I'm another developer working on this project with tstorb1)

                   

                  Thanks for your reply rfrishbe. I'm afraid we may not have fully explained the situation. Let me add some details on the project:

                   

                  1. Using Flash Builder Beta for programming

                  2. Using a MySQL database

                  3. Using PHP as the data services language

                  4. Using 2 tables (thus 2 data services)

                   

                  This is just a simple application for testing purposes to start familiarizing ourselves with FLEX.

                   

                  The goal here is to switch the dataProvider from one table to the other, while getting the id of the element that was double clicked on, and passing it as a search parameter to the second dataProvider.

                   

                  The code tstorb1 posted above is our current mxml file. If you would like we could also post the entire project. I've done quite a bit of debugging already. Everything works except for this line of code:

                  getAllItemsResult2.token = subcategories.getAllItems(item.id);

                   

                  If this line is placed under the creationComplete event handler it works fine (with a static search parameter), but then you cant pass it the value of a double clicked element. Switching dataProviders works just fine too. So the question is, how do we switch dataProviders, while redefining the search parameter each time an element is doubleClicked? Its somewhat difficult to describe, but any help would really be great.

                  • 6. Re: Relating 2 tables with one List Control
                    Justin Schroeder Level 1

                    Sreenivas R wrote:

                     

                    The following code doesn't work

                     

                    category.dataProvider = TypeUtility.convertToCollection(getAllItemsResult2.lastResult);

                     

                    because the service call "subcategories.getAllItems" is made asynchronously. A result event is dispatched when the result has been obtained from the server.

                     

                    If you move the assignment to the result event handler of the CallResonder as follows it should work.

                     

                    <s:CallResponder id="getAllItemsResult2"  result="category.dataProvider = TypeUtility.convertToCollection(getAllItemsResult2.lastResult)"/>

                     

                    -Sreenivas

                     

                    Awesome! This works. I'm still an infant in flex, so I dont fully understand the purpose of the CallResponder. I read the little adobe snippet on CallResponders in Flex Builder, but their scope is still pretty foggy in my mind. Would you mind explaining them a little further, or pointing me somewhere I can learn more about them?

                     

                    Thanks so much for your help!

                    • 7. Re: Relating 2 tables with one List Control
                      tlaneadobe

                      Hi Justin. Let me take a shot at explaining asynchronous calls. Most PHP developers are used to calling functions in one way only: synchronously. In ActionScript a sychronous function call looks like this:

                       

                      var stuff = getStuff();

                       

                      Pretty straightforward. It's how you expect functions to work: you call them, and then immediately on line #2 of this example you have a value in the stuff variable to work with.

                       

                      But when it comes to calling remote functions on services sitting on a server somewhere, Flex calls them asynchronously. This is so that the Flex client can continue working while the request is pending. An aync call looks more like this (at least, the first part):

                       

                      responder.token = getStuffFromService();

                       

                      What this means is, "stuff" does not come back right away as the result of the function. Instead, what it returns is a kind of ticket. Sort of like ordering some food from a lunch counter and getting a receipt with a number on it. You don't get your food right away. Instead, you go hang out or do some other stuff while your order is pending, and then your number is called when it's ready. And then you "respond" to your number.

                       

                      Well, that's what a CallResponder is. When you "place your order", you hook up a CallResponder to it. When your order is ready (data comes back from the service call), the responder kicks into action. It fires a result event (or a fault if something went wrong), and it updates its bindable lastResult property.

                       

                      So, if you want to work with data from an async call, you can't simply do it on line #2 of the above snippet. You have to wait until the CallResponder for that call gets its result. If you create a databinding to lastResult, that will automatically update when the result is ready. But since you want to run some script on the result, you have to trigger that script from the CallResponder's result event handler.

                       

                      Does that help? Async is definitely a new concept for many web developers to wrap their heads around. But it lets you build some interesting UIs once you get the hang of it.

                       

                      Best,

                      Tom

                      • 8. Re: Relating 2 tables with one List Control
                        Justin Schroeder Level 1

                        Tom,

                         

                        Thank you so much for that explanation, it makes much more sense now. I do come from a php background, so all this stuff is quite new to me. Thanks again.