First real post here, and it's not a SO difficult thing, but it deserves a post. It'll also be used as an experiment to see how GeSHi plugin of Serendipity works.
I work in project here where I'm building a prototype using Flex + Symfony + Doctrine.
My scenario: I had to populate a combobox component from an XML provided by server. The XML format is this:
<?xml version="1.0" encoding="utf-8"?>
<response>
<status>OK</status>
<message/>
<data>
<item id="1" label="Foo"/>
<item id="2" label="Bar"/>
<item id="3" label="Baz"/>
</data>
</response>
I have a wrapper to HTTPService which handles for non-status OK and Alerts the message. If it's ok, call result as it should. So, my interested data is everything under "data" node.
I wrote then a simple combo component to handle my wish:
<?xml version="1.0" encoding="utf-8"?>
<mx:ComboBox xmlns:mx="http://www.adobe.com/2006/mxml" labelField="@label" dataProvider="{itemService.lastResult.data.item}" creationComplete="itemService.send()">
<mx:HTTPService id="itemService" method="POST" url="module/action" useProxy="false" resultFormat="e4x"/>
</mx:ComboBox>
With all the Flex magic, it worked well, but 2 warnings in Builder console started to drive me crazy. Those were the warnings:
warning: unable to bind to property 'data' on class 'XML' (class is not an IEventDispatcher)
warning: unable to bind to property 'item' on class 'XMLList' (class is not an IEventDispatcher)
I tried to place under a result event, with warning still flashing me. After a lot of research, I found that was because of lack of castings. Then I started a furious write-and-try to get rid of it.
After a hundred tries, I found my solution. Here it is:
dataProvider="{XMLList(XMLList(XML(itemService.lastResult).data)[0].item)}"
I know, it's ugly.... but it works.
On IRC (irc.freenode.net channel #flex) one user told me I was probably driving compiler crazy. I don't think so, because the performance increased quite a bit.
Let me explain what I found as how compiler understands it.
itemService.lastResult always return the XML response. It's not a XMLListCollection, so don't even try to change that.
This cast was necessary because you cannot cast to an XMLList without previously casting an XML. I tried to cast "data" as XML, but it told me I could not cast an unknown variable that could not be an XML. So I casted the lastResult as the XML, then I tried to cast "data" as XML too, and compiler gave me another warning, telling I was trying to cast an XMLList into an XML. That was easy... I casted to an XMLList then and retrieved the 0 index. The last thing remaining was the XMLList casting of items... I tried to follow Adobe's recommendation (always use XMLListCollection as dataProvider), but didn't work either.
So, if you experience the same thing, feel free to do the same thing I've done. Most people usually return the response directly, like:
<?xml version="1.0" encoding="utf-8"?>
<response>
<item id="1" label="Foo"/>
<item id="2" label="Bar"/>
<item id="3" label="Baz"/>
</response>
For you guys, you'll never need my "hack". If you use this approach, itemService.lastResult is already an XML, and the following children will be always treated as XMLList.
BBBUUUTTT.... if you want to help compiler, do:
dataProvider="{XMLList(XML(itemService.lastResult).item)}"
That's all folks!