views:

253

answers:

2

I'm fetching some data from a PHP application using Zend AMF. However I can't get the data to bind to a simple DropDownList control. The PHP method is:

class Test
{
    public function myMethod()
    {
        $res = array();
        $res[] = array('NAME' => 'ThisIsATest', 'ID' => 1);
        return $res;
    }
}

Network Monitor reports the method is returning results. It's returning the following as an array:

Array
(
    [0] => Array
        (
            [NAME] => Property
            [ID] => 1
        )
)

Below is the Flex code:

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
                       xmlns:s="library://ns.adobe.com/flex/spark"
                       xmlns:mx="library://ns.adobe.com/flex/mx"
                       width="500" height="286"
                       creationComplete="initApp()">
    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            import mx.rpc.events.FaultEvent;
            import mx.rpc.events.ResultEvent;

            private function myMethodResult(e:ResultEvent):void
            {
                searchType.dataProvider = e.result as ArrayCollection;
            }

            protected function initApp():void
            {
                service.myMethod();
            }

            protected function faultHandler(event:FaultEvent):void
            {
                trace(event.fault.faultString);
            }
        ]]>
    </fx:Script>
    <fx:Declarations>
        <s:RemoteObject id="service"
                        destination="zend"
                        source="Test"
                        showBusyCursor="true"
                        fault="faultHandler(event)">
            <s:method name="myMethod" result="myMethodResult(event)"/>
        </s:RemoteObject>
    </fx:Declarations>
    <s:DropDownList id="searchType" labelField="NAME"/>
</s:WindowedApplication>

Any help would be greatly appreciated. Thanks in advance.

+2  A: 

You ask about binding, but I don't think that's what you want to know about. I believe the answer is this line in the result handler:

searchType.dataProvider = e.result as ArrayCollection;

I'm assuming that you are getting back an Array from ColdFusion. If memory serves me, you cannot cast an array as an ArrayCollection. The result will, most likely, be null. Have you stepped through code in debug mode to verify?

Instead try this:

searchType.dataProvider = new ArrayCollecection(e.result as Array);

Since e.result is a generic object, you'll need to cast it as an array.

To address the binding portion of your answer. Binding has a source and a value. When the source changes, the value is automatically updated. You have a value ( dropDownList.dataProvider ) that you want to change, but you do not have a source for that. Nothing in your code makes use of binding. You're just manually setting the value when the results come back. To make use of binding I might modify your code like this:

    <?xml version="1.0" encoding="utf-8"?>
    <s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
                           xmlns:s="library://ns.adobe.com/flex/spark"
                           xmlns:mx="library://ns.adobe.com/flex/mx"
                           width="500" height="286"
                           creationComplete="initApp()">
        <fx:Script>
            <![CDATA[
                import mx.collections.ArrayCollection;
                import mx.rpc.events.FaultEvent;
                import mx.rpc.events.ResultEvent;

// create a variable taht can be used as the source for a binding operation
[Bindable]
public var mySource : ArrayCollection;

                private function myMethodResult(e:ResultEvent):void
                {
//                    searchType.dataProvider = e.result as ArrayCollection;
// change the value of your binding source
mySource = new ArrayCollection(e.result);
                }

                protected function initApp():void
                {
                    service.myMethod();
                }

                protected function faultHandler(event:FaultEvent):void
                {
                    trace(event.fault.faultString);
                }
            ]]>
        </fx:Script>
        <fx:Declarations>
            <s:RemoteObject id="service"
                            destination="zend"
                            source="Test"
                            showBusyCursor="true"
                            fault="faultHandler(event)">
                <s:method name="myMethod" result="myMethodResult(event)"/>
            </s:RemoteObject>
        </fx:Declarations>
<!-- and finally, specify your dataProvider as the target for binding -->
        <s:DropDownList id="searchType" labelField="NAME" dataProvider="{this.mySource }"/>
    </s:WindowedApplication>

I wrote all code in a browser and it may not be "compile perfect"

www.Flextras.com
A: 

@Flextras

searchType.dataProvider = new ArrayCollecection(e.result);

...resulted in...

1118: Implicit coercion of a value with static type Object to a possibly unrelated type Array.

Instead I tried...

searchType = ArrayCollection(e.result);

But this resulted in...

Error #1034: Type Coercion failed: cannot convert []@812a1c9 to mx.collections.ArrayCollection

Then I tried...

typeArray.source = e.result as Array;

...and...

<s:DropDownList labelField="NAME">
    <s:ArrayCollection id="typeArray"/>
</s:DropDownList>

This works! \o/

Reado
As I said in my answer: "It may be possible you'll need to cast e.result (a generic object) as an array, but I don't think so." I bet this would have worked: searchType.dataProvider = new ArrayCollecection(e.result as Array);. If you think my answer helped you, be sure to mark it as correct and/or give it an upvote.
www.Flextras.com
I've marked it as correct and up-voted. Thanks for your help.
Reado
I appreciate the Karma points; thanks!
www.Flextras.com