Blog Stats
  • Posts - 8
  • Articles - 0
  • Comments - 4
  • Trackbacks - 0

 

Web Services and ArrayCollections in Adobe FLEX 2: How to Successfully Read Any Number of XML Nodes

I am learning Flex 2 for a project I'm working on with a friend.  We decided, for simplicity's sake, to have our web service connection to the back-end be relatively simple to begin with:  Just use HTTP POST.  But we ran into a snag, which, in doing a search on Google, I discovered that many others have run into.

When you use a web service to pull a list of XML nodes into Adobe Flex, what happens is that Flex generates a "result" object that contains the xml you're trying to read in.  As the Flex developer, you're expected to declare an object of type ArrayCollection, set it equal to the ArrayCollection in the Result collection, and you're good to go.  Frustratingly, that's where a lot of the documentation I found on this ends, and it's not the whole picture.  The problem is with that ArrayCollection in the Result object that Flex creates for you:  The problem is it does NOT always do it!  It only does it in cases where it "has to," that is, for xml containing node lists with a count of 2 or more.

More specifically:

  • For node lists of two or more nodes, Flex recognizes that it "needs" an ArrayCollection to contain them, and creates the ArrayCollection in the Result object to contain them.
  • For node lists of exactly one node, Flex recognizes that it "needs" to only create a single-object container, and chooses to do this by creating an object of type ObjectProxy in the Result object to contain it.  For consistency in your application, I would recommend that you use Flex' toArray() function to convert the ObjectProxy to ArrayCollection. 
  • For node lists of exactly zero nodes, Flex decides, rightly so, to set its internal representation of the node collection to NULL.  In that case, for consistency, I would recommend that you simply create an empty ArrayCollection.

Sample code is below.  I've included the web service "mx:HTTPService" definition and its call to the parsing function.

 

    <mx:Script>
    <![CDATA[
        import mx.collections.ArrayCollection;
        import mx.utils.ObjectProxy;
        import mx.rpc.events.ResultEvent;
        import mx.controls.Alert;
        import mx.utils.ArrayUtil;
        [Bindable]
        private var reminderList:ArrayCollection;
        private function ParseReminderList(event:ResultEvent):void
        {               
            if (event.result.Reminders == null)
            {
                reminderList=new ArrayCollection()
            }
            else if (event.result.Reminders.Reminder is ArrayCollection)
            {
              reminderList=event.result.Reminders.Reminder;
            }
            else if (event.result.Reminders.Reminder is ObjectProxy)
            {
               reminderList = new ArrayCollection(ArrayUtil.toArray(event.result.Reminders.Reminder));
            }
        }
    ]]>
        </mx:Script>
<mx:HTTPService id="ReminderListService" url="http://localhost/reminders.asp" result="ParseReminderList(event)"/>

Print posted @ Tuesday, February 26, 2008 9:30 AM


Feedback

# re: Web Services and ArrayCollections in Adobe FLEX 2: How to Successfully Read Any Number of XML Nodes

Gravatar

ps. -- Also as part of my researches in Google on this, this arrangement is almost univesally considered a bug.  I don't agree with that.  It is, at most, a feature, and I'd even argue with that, too.  Once you understand what Flex is actually doing with this under the covers and why, it makes sense.  Yes, it's less convenient for us.  Yes, Adobe should strongly consider including a helper function in the next version of ActionScript that will do this for us.  And, God yes, they need to document this better.  But in terms of what Flex/ActionScript is actually doing, I wouldn't mess with it.  It's clean and logical.  And that's a breath of fresh air, to me.

2/26/2008 9:35 AM | ebuatois

Post a comment





 

Please add 4 and 4 and type the answer here:

 

 

Copyright © Edward Buatois