14 Replies Latest reply on Jun 15, 2009 11:08 AM by Handycam

    Mimicking a simple HTTPService for an XML file

    Handycam Level 1

      The thing I do more than anything in Flex (2 and 3) is to request an XML file and process the returned E4X-formatted data.  Hands down, the thing I do most.  And it's been pretty easy and flexible.

       

      I downloaded the Flash Builder beta, and apparently this no longer works.  Looks like instead there is a complex "services" UI, which I cannot figure out how to configure to request a simple XML file, return the data as E4X, and fire a RPC result handler to process it.

       

      Can someone please briefly explain to me the procedure in FB4 that is meant to replace the httpservice in Flex 3? Until then, I have no way to use FB4.

       

      Thanks.

        • 1. Re: Mimicking a simple HTTPService for an XML file
          tlaneadobe Level 1

          Hi- Have you tried using the HTTP Service option in the service wizard? I'd like to understand exactly where it confused you.. Was it that you didn't realize that option was there? Was it that you couldn't figure out the configuration UI in the wizard for adding a service operation that pointed at an XML file? Was it that you couldn't figure out how to hook up an event handler? Something else?

           

          By the way, you can still do exactly what you used to do in Flex 3 with Flash Builder 4, i.e. hand code an HTTPService. So you should be able to use FB4 even if you don't use the new services UI.

           

          -Tom

          • 2. Re: Mimicking a simple HTTPService for an XML file
            Handycam Level 1

            Well, the first thing I tried when firing up the beta was to create one the "old way".  No encouraging since the is no code suggest for it, but I typed one out anyhow but get a build error of

             

            'HTTPService' declaration must be contained within the <Declarations> tag since it does not implement mx.core.IUIComponent.

             

            No idea what that means. sorry.

             

            So then I tried the wizard.  Looked promising, clicked "HTTPService".  But then the next dialog I had no idea what to do, other than name my service and put the URL to my XML file (which is currently local, in the SRC folder).

             

            See attached annotated screen shot.

             

            I'd love to start testing this, but this prevents me for most work.

            • 3. Re: Mimicking a simple HTTPService for an XML file
              Handycam Level 1

              Oh, and I even tried taking it "further" by clicking OK here, and reading the complicated instructions.  I created a datagrid and went to design view and tried "bind to data", but was unable to figure out that series of dialog boxes either.

               

              How could something that was so simple have gotten so complex?

              • 4. Re: Mimicking a simple HTTPService for an XML file
                tlaneadobe Level 1

                Thanks for the annotated screenshot! Ok, you're encountering two hurdles:

                 

                1) In Flex 4 (the language), MXML now requires non-visual component declarations to go inside of an fx:Delcarations block. So I lied a little bit when I said you could do things exactly the same way.. I meant, you can still code mx:HTTPService they way you used to, but it has to go inside fx:Declarations.

                 

                2) You're encountering usability issues with the HTTP service config UI. I'll log a bug on this, hopefully we'll be able to improve it / simplify it. But to explain what you're seeing, the key thing to understand is that the wizard lets you define multiple operations with an HTTP service. Whereas previously you just have one URL per HTTPService declaration, now you can have multiple URLs, each of which you can assign an operation name. We did this so you can define a REST-style service. Admittedly, this makes the "I just want to point at one URL" case harder. In your case, you just want to define one operation (the fill_in_name part) and fill in your XML URL to the right of that. Beyond that, the parameters section is just a way to break out the query string parameters on the URL and assign them datatypes.

                 

                Hope that helps. I'd love to see how much further you can get after you get past this wizard. We definitely are listening to beta feedback and will try to smooth things out as best we can before the final release.

                 

                Best,

                Tom

                • 5. Re: Mimicking a simple HTTPService for an XML file
                  Handycam Level 1

                  tlaneadobe wrote:

                   

                  In your case, you just want to define one operation (the fill_in_name part) and fill in your XML URL to the right of that.

                   

                  OK, I guess I don't understand what an "operation" would be.  I got it to work the "old" way, as below, but I am unsure how to replicate this using the new UI.  What I need to do is, as you can see, fetch a URL and pass the event to an RPCResultEvent handler "processData()". Where in the new UI do I specify that my service is to fetch result format E4X and then call processData()?

                   

                  <?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" creationComplete="tableData.send()">

                  <fx:Script>

                  <![CDATA[

                  import mx.rpc.*;

                  import mx.events.ListEvent;

                  import mx.rpc.events.FaultEvent;

                  import mx.rpc.events.ResultEvent;

                  import mx.collections.XMLListCollection;

                  [Bindable] private var dataXML:XMLListCollection = new XMLListCollection();

                   

                  private function processData(e:ResultEvent):void{

                  var list:XMLList = new XMLList(e.result..item);

                          dataXML = new XMLListCollection(list);

                  }

                   

                  private function processFault(e:FaultEvent):void {

                  trace(e.fault);

                  }

                   


                  ]]>

                  </fx:Script>

                  <fx:Declarations>

                    <mx:HTTPService id="tableData" url="tabletext.xml" resultFormat="e4x" result="processData(event)" fault="processFault(event)" />

                  </fx:Declarations>


                   

                  </s:Application>

                  • 6. Re: Mimicking a simple HTTPService for an XML file
                    SrinivasAnnam Adobe Employee

                    Hi,

                     

                      You could get yourself introduced to Data Centric Development (DCD) workflow of FlashBuilder 4 from here

                          http://srinivasannam.wordpress.com/2009/06/01/introduction_to_dcd/

                     

                      Direct tutorial for using HTTPService using DCD workflow can be found below

                         http://sujitreddyg.wordpress.com/2009/06/04/connecting-to-http-services-with-the-data-cent ric-development-dcd-feature-in-flash-builder-4/ 

                     

                    Regards

                    Srinivas Annam - Adobe

                    http://srinivasannam.wordpress.com

                    • 7. Re: Mimicking a simple HTTPService for an XML file
                      Handycam Level 1

                      I will read this more carefully and give it a try.  At first glance, it

                      looks insanely complicated to just fetch and use a simple XML file.  For the

                      example given of Yahoo Weather, perhaps.  But to fetch a bunch of questions

                      for a quiz, overkill IMHO.

                      • 8. Re: Mimicking a simple HTTPService for an XML file
                        tlaneadobe Level 1

                        Hi, as promised I've logged an issue on simplifying the wizard UI for the case of a single URL service. https://bugs.adobe.com/jira/browse/FB-20380

                         

                        I've also logged one on e4x support. https://bugs.adobe.com/jira/browse/FB-20349 . In the meantime the alternative is to just not use e4x, but rather let us generate value objects for you to work with via the Configure Return Type feature.

                         

                        If you like, please vote for them or add some comments. Votes make a difference. The other confusion you're encountering is our pattern for calling services.

                         

                        HTTPService way:

                         

                        From your code...

                         

                        creationComplete="tableData.send()"


                        <mx:HTTPService id="tableData" url="tabletext.xml" resultFormat="e4x" result="processData(event)" fault="processFault(event)" />

                         

                        Service wrapper way (single operation only):

                         

                        You can actually do the same thing with a service created with the wizard. Assume you name the service "TableService" and add an operation "send" that points at tabletext.xml:

                         

                        creationComplete="tableData.send()"


                        <tableService:TableService id="tableData" result="processData(event)" fault="processFault(event)"/>

                         

                        But, that only works if your service has a single operation.

                         

                        Multi-operation service wrapper way:

                         

                        creationComplete="getTableTextResponder.token = tableService.getTableText()"


                        <tableservice:TableService id="tableService"/>

                        <s:CallResponder id="getTableTextResponder" result="processData(event)" fault="processFault(event)"/>

                         

                        This is admittedly harder for the simple case you cite. But it supports services with multiple operations, by assigning a responder to each call that has its own result/fault event handlers.

                         

                        Any thoughts on that or how we could make it easier / more learnable?

                        • 9. Re: Mimicking a simple HTTPService for an XML file
                          Handycam Level 1

                          tlaneadobe wrote:

                           

                          In the meantime the alternative is to just not use e4x, but rather let us generate value objects for you to work with via the Configure Return Type feature.

                           


                           

                          I'm not sure how this works.  I finally got used to E4X and find it very flexible to work with.  Take one of the apps I work with, Create Your Own Recipe

                           

                          These apps load an XML file with nodes such as:

                           

                           

                          <step minimum="1" maximum="2" isoptional="true">
                               <stepTitle>Additions</stepTitle>     
                               <ingredientList>
                                    <prompt>Choose one or two (optional):</prompt>
                                    <items>
                                    <item ln1="Chocolate" ln2="bittersweet chocolate (at least 60% cacao), chopped and melted" sn="melted chocolate" qty="4" units="oz." img="02chocolate.jpg" />
                                    <item ln1="Peaches" ln2="fresh peaches (or 1-1/3 lb. frozen), peeled, pitted, cooked to soften, and puréed" sn="peach purée" qty="1-1/2" units="lb." img="02peaches.jpg" />
                                    <item ln1="Strawberries" ln2="fresh or frozen strawberries, puréed, strained, and mixed with 1/2 cup sugar" sn="strawberry purée" qty="1" units="lb." img="02strawberries.jpg" />
                                    <item ln1="Raspberries" ln2="fresh or frozen raspberries, puréed, strained, and mixed with 1/3 cup sugar" sn="raspberry purée" qty="12" units="oz." img="02raspberries.jpg" />
                                    </items>
                               </ingredientList>
                               <bodyText>After the custard is cooked, you can layer in even more flavor by adding chocolate, fruit purées, juices, liqueurs, or even olive oil. For super-intense flavor, pick an addition that echoes the infusion you chose -- for instance, lemon zest plus lemon juice. Or choose a complementary flavor.</bodyText>
                          </step>
                          

                           

                           

                          I process the returned data and assign it to an XMLListCollection:

                           

                           

                          private function dataHandler(event:ResultEvent):void {
                                    var list:XMLList = new XMLList(event.result..step);
                                            dataXML = new XMLListCollection(list);
                                            introXML = new XMLList(event.result.intro);
                                            theYield = introXML.yield;
                                            theTitle = introXML.introTitle;
                                       
                                    }
                          

                           

                           

                          And then use is throughout the application, such as:

                           

                           

                          <mx:ApplicationControlBar id="appBar" dock="false" verticalAlign="middle" width="100%" y="64">
                                    <mx:Repeater id="toolbar" dataProvider="{dataXML}" >
                                    <mx:Button id="toolbarButtons" label="{toolbar.currentIndex+1}. {toolbar.currentItem..stepTitle}" enabled="false" styleName="toolbarButtons" />
                                    </mx:Repeater>
                               </mx:ApplicationControlBar>
                          

                           

                           

                          I'm not sure how to use a "value object" to accomplish the same thing. The rest of your post was extremely helpful, though, thank you.

                           

                          As for "making it easier" perhaps in the wizard when using a "flat" file such as an XML text file (or a PHP file that returns XML) we can browse what it returns, similar to when creating a connection/behavior in Dreamweaver?

                          • 10. Re: Mimicking a simple HTTPService for an XML file
                            tlaneadobe Level 1

                            Glad it was helpful.. You make total sense and hopefully we can get a simpler wizard UI and e4x support via those bugs I filed. All depends on how we prioritize things (voting helps).

                             

                            To explain how you would do it with value objects a bit (a.k.a. "data types"), basically you can do almost exactly the same thing, only instead of using e4x and XMLList you just use regular ActionScript objects. So the equivalent code would look something like:

                             

                            var stepArray:Step[];   // instead of dataXML

                            private function dataHandler(event:ResultEvent):void {
                                 stepArray = event.result.recipe.step;
                                 theTitle = event.result.intro.introTitle;
                            }

                             

                            Where Step is a data type class automatically generated for you by the Configure Return Type wizard. The other thing that is different is instead of using an e4x expression to find the step list (the double-dot event.result..step), you use the full object path to it. I guessed "recipe" is the root node of step in your XML doc.. adjust accordingly.

                             

                            Also, you could bind your mx:Repeater directly to your {callResponder.lastResult.recipe.step} , using that new CallResponder pattern I mentioned. What's cool about this is you'll get code hints on lastResult -- i.e. we'll hint "recipe" and then "step", so we help you write a correct expression!

                            • 11. Re: Mimicking a simple HTTPService for an XML file
                              Handycam Level 1

                              Thanks but I am still stuck trying to do it will the wizard.  I decided to give it a shot on a new project, where I've got an xml file full of nodes like:

                               

                               

                              <?xml version="1.0" encoding="UTF-8"?>
                              <wizarddata>
                              
                              <group name="Demoliton and Structural Changes">
                              <step name="Kitchen access">
                                   <items>
                                        <item>Direct; less than 3 ft. above grade</item>
                                        <item>Direct; one story above grade</item>
                                        <item>Indirect; less than 3 ft. above grade</item>
                                        <item>Indirect; one story above grade</item>
                                        <item>Indirect; more than one story above grade</item>
                                   </items>
                                   <tip title="Kitchen access">Direct access to the kitchen from a parking/loading area speeds debris removal and material delivery.</tip>
                              </step>
                              </group>
                              </wizarddata>
                              

                              So I create a new service:

                               

                              http://img.skitch.com/20090615-q1mwucp5swjw568q4c2jf71k83.jpg

                               

                              I assume this is correct.  I click "finish", get this:

                               

                              http://img.skitch.com/20090615-bnxq7yjx8kww2a11d4bhtggmmc.jpg

                               

                              OK.  So  I highlight  my getData action in the Data/Services window, and click "configure return type".  Here's where I am lost.

                               

                              http://img.skitch.com/20090615-46kmg9xn1qmk3ge6586nw8rjg.jpg

                               

                              I assume from your earlier post that I will create a new data type?  So I put "Step" in there and click to continue.  I get this:

                               

                              http://img.skitch.com/20090615-mahbyqqhaq5y6bkr18qt6gemcm.jpg

                               

                              End of story.  No idea what to do now.  Am I doing it wrong?

                              • 12. Re: Mimicking a simple HTTPService for an XML file
                                Mayank (Adobe) Adobe Employee

                                This looks like http://bugs.adobe.com/jira/browse/FB-19969.

                                 

                                It was fixed post beta, will work fine in a future release.

                                 

                                Till then you can try placing the xml files in a folder under htdocs and accessing them using the http://localhost url. To enable easy editing of those files, you can create a linked folder in your Flex project which points to the root folder containing all the xml files.

                                 

                                -mayank

                                • 13. Re: Mimicking a simple HTTPService for an XML file
                                  tlaneadobe Level 1

                                  Sounds like you're also confused by the UI. What you're supposed to do here is just click Next. We've improved that already in a post-beta build, in that we won't prompt you to fill in argument values if the operation doesn't have any arguments. Sounds like we could improve this UI further though, for when you do see it.

                                   

                                  If you do that, you'll get an error about an invalid URL. That's the bug Mayank is talking about. As he notes, to work around it in the beta use absolute URLs instead of relative. Right-click on the service in the Data Services panel, select Properties, and change the URL to an absolute one e.g. http://myserver/somewhere/wizardData.xml

                                   

                                  -Tom

                                  • 14. Re: Mimicking a simple HTTPService for an XML file
                                    Handycam Level 1

                                    Thanks Tom.  The "invalid URL' was the stopping point.

                                    On a related topic, I am a registered Adobe beta tester with other products.

                                    I'd love to get on the closed beta for FB and FC so I can get access to

                                    these follow-up builds and see if my bugs are coming along, if possible.