12 Replies Latest reply on Nov 26, 2007 5:14 AM by curtkauf

    Load web service into ArrayCollection

    curtkauf
      I can't seem to get a .Net wed service to load into an ArrayCollection. There is something I don't understand. Her is my code..

      [Bindable]
      private var serviceRevenue:ArrayCollection;

      private function runService():void{
      this.wsWeeklyReports.DataForWeek.send();
      serviceRevenue = new ArrayCollection(this.wsWeeklyReports.DataForWeek.lastResult);
      }


      <mx:WebService id="wsWeeklyReports"
      wsdl=" http://localhost:1602/CS_Webservice/WeeklyReports.asmx?wsdl"
      useProxy="false"
      fault="Alert.show(event.fault.faultString), 'Error'">


      <!-- this operation determines if the user is valid -->
      <mx:operation name="DataForWeek">
      <mx:request>
      <dteWEDate>{this.dteWEDate.selectedDate.toDateString()}</dteWEDate>
      <strType>{this.lblType.text}</strType>
      </mx:request>

      </mx:operation>

      </mx:WebService>
      <mx:ApplicationControlBar width="100%" fillColors="[#460064, #008484]">
      <mx:DateField id="dteWEDate"/>
      <mx:Button label="Run" id="btnRun" click="{runService()}"/>
      </mx:ApplicationControlBar>

      <mx:Panel title="Revenue by Date" width="100%" height="100%"
      paddingTop="10" paddingLeft="10" paddingRight="10" paddingBottom="10">

      <mx:ColumnChart id="columnChart"
      height="100%" width="100%"
      paddingLeft="5"
      paddingRight="5"
      showDataTips="true"
      dataProvider="{serviceRevenue}">
      <mx:horizontalAxis>
      <mx:CategoryAxis categoryField="date"/>
      </mx:horizontalAxis>
      <mx:verticalAxis>
      <mx:LinearAxis minimum="1" />
      </mx:verticalAxis>
      <mx:series>
      <mx:ColumnSeries xField="date" yField="total" displayName="date">
      </mx:ColumnSeries>
      </mx:series>
      </mx:ColumnChart>
        • 1. Re: Load web service into ArrayCollection
          bitwyse Level 1
          A couple things to try here. First, you should use a resultHandler in your webservice. That way if it takes a while for it to return the data you won't have to worry about populating a null collection.

          Secondly in your result handler try this:
          serviceRevenue = new ArrayCollection( new XMLListCollection( this.wsWeeklyReports.DataForWeek.lastResult).toArray() );
          • 2. Re: Load web service into ArrayCollection
            curtkauf Level 1
            Thanks for the tip on the result handler, I tried you suggestion and it didn't do anything. I tried just using the ArrayCollection in the result handler and that didn't work either. Any other ideas? Any help would be appreciated! Thanks!

            curtkauf
            • 3. Re: Load web service into ArrayCollection
              kcell Level 2
              Hello curtkauf,

              can you post the updated version which still doesn´t work.

              best regards,
              kcell
              • 4. Re: Load web service into ArrayCollection
                curtkauf Level 1
                Kcell,

                Can't tell you how much I appreciate your interest and help....here is the code with the error message following:

                <?xml version="1.0"?>
                <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml"
                backgroundColor="#FFFFFF">

                <mx:Script>
                <![CDATA[
                import mx.charts.events.ChartItemEvent;
                import mx.rpc.events.*;
                import mx.charts.ChartItem;
                import mx.charts.chartClasses.ChartBase;
                import mx.collections.ArrayCollection;
                import mx.collections.XMLListCollection;
                import mx.charts.HitData;
                import mx.controls.Alert;

                [Bindable]
                private var serviceRevenue:ArrayCollection;

                private function runService():void{
                this.wsWeeklyReports.DataForWeek.send();
                serviceRevenue = new ArrayCollection(this.wsWeeklyReports.DataForWeek.lastResult);
                }

                private function resultHandler(event:ResultEvent):void {
                serviceRevenue = new ArrayCollection
                (new XMLListCollection(this.wsWeeklyReports.DataForWeek.lastResult).toArray());
                }


                ]]>
                </mx:Script>

                <mx:WebService id="wsWeeklyReports"
                wsdl=" http://localhost:1602/CS_Webservice/WeeklyReports.asmx?wsdl"
                useProxy="false"
                fault="Alert.show(event.fault.faultString), 'Error'"
                result="resultHandler(event)">


                <!-- this operation determines if the user is valid -->
                <mx:operation name="DataForWeek">
                <mx:request>
                <dteWEDate>{this.dteWEDate.selectedDate.toDateString()}</dteWEDate>
                <strType>{this.lblType.text}</strType>
                </mx:request>

                </mx:operation>

                </mx:WebService>
                <mx:ApplicationControlBar width="100%" fillColors="[#460064, #008484]">
                <mx:DateField id="dteWEDate"/>
                <mx:Button label="Run" id="btnRun" click="{runService()}"/>
                <mx:Label id="lblType" text="R" />
                </mx:ApplicationControlBar>

                <mx:Panel title="Revenue by Date" width="100%" height="100%"
                paddingTop="10" paddingLeft="10" paddingRight="10" paddingBottom="10">

                <mx:ColumnChart id="columnChart"
                height="100%" width="100%"
                paddingLeft="5"
                paddingRight="5"
                showDataTips="true"
                dataProvider="{serviceRevenue}">
                <mx:horizontalAxis>
                <mx:CategoryAxis categoryField="date"/>
                </mx:horizontalAxis>
                <mx:verticalAxis>
                <mx:LinearAxis minimum="1" />
                </mx:verticalAxis>
                <mx:series>
                <mx:ColumnSeries xField="date" yField="total" displayName="date">
                </mx:ColumnSeries>
                </mx:series>
                </mx:ColumnChart>
                </mx:Panel>
                </mx:Application>

                Here is the error I'm getting:

                TypeError: Error #1034: Type Coercion failed: cannot convert mx.collections::ArrayCollection@683a8e1 to XMLList.
                at Test_ArrayCollection/::resultHandler()
                at Test_ArrayCollection/__wsWeeklyReports_result()
                at flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEventFunction()
                at flash.events::EventDispatcher/dispatchEvent()
                at mx.rpc::AbstractService/dispatchEvent()
                at mx.rpc.soap.mxml::WebService/dispatchEvent()
                at mx.rpc::AbstractOperation/ http://www.adobe.com/2006/flex/mx/internal::dispatchRpcEvent()
                at mx.rpc::AbstractInvoker/ http://www.adobe.com/2006/flex/mx/internal::resultHandler()
                at mx.rpc::Responder/result()
                at mx.rpc::AsyncRequest/acknowledge()
                at ::DirectHTTPMessageResponder/completeHandler()
                at flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEventFunction()
                at flash.events::EventDispatcher/dispatchEvent()
                at flash.net::URLLoader/flash.net:URLLoader::onComplete()

                This seems like this should be easy but I am missing some basic concept with ArrayCollections and .Net Web Services. Again, Thanks so much for helping me.

                curtkauf
                • 5. Re: Load web service into ArrayCollection
                  kcell Level 2
                  curtkauf,

                  no problem, forums are there to spread knowledge and solve problems.

                  To your problem:
                  1)"TypeError: Error #1034: Type Coercion failed: cannot convert mx.collections::ArrayCollection@683a8e1 to XMLList.
                  at Test_ArrayCollection/::resultHandler()
                  at Test_ArrayCollection/__wsWeeklyReports_result()"

                  The error occure in the resulthandler, some conversion get wrong. Currently "lastResult" already seems to return an ArrayCollection. So you should try to use your old code in the resulthandler

                  private function resultHandler(event:ResultEvent):void {
                  if ( this.wsWeeklyReports.DataForWeek.lastResult is ArrayCollection)
                  serviceRevenue = new ArrayCollection(this.wsWeeklyReports.DataForWeek.lastResult);
                  else
                  {
                  // this code is executed when lastresult is not an arraycollection (of objectproxies)
                  // we assume it is an objectproxy
                  serviceRevenue = new ArrayCollection();
                  serviceRevenue .push(this.wsWeeklyReports.DataForWeek.lastResult);
                  }


                  }

                  I have just written this code down, I have not tested if this is correct code (but I hope so ;) )

                  2) don´t assign lastresult after send in the "runservice" function (its obsolete)
                  private function runService():void{
                  this.wsWeeklyReports.DataForWeek.send();
                  }

                  best regards,
                  kcell
                  • 6. Re: Load web service into ArrayCollection
                    ntsiii Level 3
                    Note that if you do not specify resultFormat in the WebService, flex converts your xml into a nested object structure.

                    This can be a simple way to get an array from your xml, but is not best practice.

                    You should use resultFormat="e4x". With some web services, however, this introduces namespace issues, so be aware.

                    If you want to use an array collection as a dataProvider, it is best to loop through the e4x xml and build an arrayCollection of strongly typed objects. This approach is the best from a performance standpoint.

                    Tracy
                    • 7. Re: Load web service into ArrayCollection
                      kcell Level 2
                      (@ntsii): I agree with you, resultformat="e4x" will decrease the performance, but curtkauf asked for a solution for his current code and I didn´t want to confuse him with another resultformat (all problems can be solved with more than one solution ).
                      When curtkauf's problem is solved, I also recommend to introduce "e4x" to his code to be prepared for the future ;)

                      best regards,
                      Kcell
                      • 8. Re: Load web service into ArrayCollection
                        curtkauf Level 1
                        You folks are all great! I really appreciate you assistance. I ended up getting it to work and the ArrayCollection doesn't seem to be a problem anymore. However, I am now moving forward and trying to use a web service that's result is in xml. I am having difficulty. The debugger says the result is there it just doesn't seem that I can access it. I have tried setting the resultFormat="e4x" and my xmlResult object has nothing in it; But the result is there. I have copied an application example that works, works until I try to use it with my service. Here is the code and that is followed by my xml file:

                        <?xml version="1.0" encoding="utf-8"?>
                        <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" layout="absolute" xmlns="*"
                        creationComplete="runService()" >
                        <mx:Script>
                        <![CDATA[
                        import mx.controls.dataGridClasses.DataGridColumn;
                        import mx.rpc.events.ResultEvent;
                        import mx.managers.CursorManager;
                        import mx.controls.Alert;

                        default xml namespace = " http://localhost:1602/CS_Webservice"; //necessary to access the xml elements easily

                        [Bindable]private var _xmlResult:XML;
                        [Bindable]private var _xlDayData:XMLList;
                        [Bindable]private var _sPlace:String;

                        /** invokes the web service operation to get the daily revenue */
                        private function runService():void
                        {
                        CursorManager.setBusyCursor();
                        WS.WE_DataSummary.send();
                        }

                        /** called by the WebService result event. Sets the dataProviders as necessary */
                        private function onResult(oEvent:ResultEvent):void
                        {
                        _xmlResult = XML(oEvent.result);
                        var xmlResultNode:XML = _xmlResult.WE_DataSummaryResult[0];
                        var xmlDetailsNode:XML = xmlResultNode.Days[1];
                        outputInfo.text = _xmlResult.toXMLString();
                        _sDayRev = xmlResultNode.ShipDate.text() + ", " + xmlResultNode.RevenueTotal.text();
                        _xlDayData = xmlDetailsNode.Services;

                        }//onResult

                        /** labelFunction for DataGrid. It seems that the namespace on the xml makes
                        * using the DataGridColumn dataField not work. At least I couldn't get it to work. */
                        private function lfDayData(oItem:Object, dgc:DataGridColumn):String
                        {
                        var sReturn:String = "";
                        var xmlItem:XML = XML(oItem); //get the item object cast as an xml object
                        var sHeaderText:String = dgc.headerText; //get the header text for this column
                        switch (sHeaderText) //logic to determine which node to get the data from
                        {
                        case "Shipments":
                        sReturn = xmlItem.Shipments.text();
                        break;
                        case "Revenue":
                        sReturn = xmlItem.Revenue.text();
                        break;
                        case "Weight":
                        sReturn = xmlItem.Weight.text();
                        break;
                        }

                        return sReturn;
                        }

                        ]]>
                        </mx:Script>

                        <mx:WebService id="WS" wsdl=" http://localhost:1602/CS_Webservice/WeeklyReports.asmx?wsdl"
                        useProxy="false"
                        fault="Alert.show(event.fault.faultString), 'Error'"
                        result="onResult(event)"
                        >

                        <!-- this operation determines if the user is valid -->
                        <mx:operation name="WE_DataSummary" resultFormat="e4x">
                        <mx:request>
                        <dteWEDate>{date.text}</dteWEDate>
                        </mx:request>
                        </mx:operation>
                        </mx:WebService>

                        <mx:Panel title="WebService" height="75%"
                        paddingTop="10" paddingBottom="10" paddingLeft="10" paddingRight="10" id="myPanel">
                        <mx:TextArea x="200" width="400" height="250" id="outputInfo" />
                        <mx:HBox>
                        <mx:Label width="100%" color="blue"
                        text="Enter a date."/>
                        <mx:TextInput id="date" text="10-4-2007"/>
                        <mx:Button label="Get daily revenue" click="runService()"/>
                        </mx:HBox>

                        <mx:Text id="txtDayRev" htmlText="{_sDayRev}"/>
                        <mx:DataGrid dataProvider="{_xlDayData}" height="180">
                        <mx:columns>
                        <mx:DataGridColumn labelFunction="lfDayData" headerText="Day" width="200" />
                        <mx:DataGridColumn labelFunction="lfDayData" headerText="High" width="100" />
                        <mx:DataGridColumn labelFunction="lfDayData" headerText="Low" width="100" />
                        </mx:columns>
                        </mx:DataGrid>

                        </mx:Panel>
                        </mx:Application>


                        .....xml data


                        <?xml version="1.0" encoding="utf-8" ?>
                        - <NewDataSet>
                        - <Days>
                        <ShipDate>2007-09-28T00:00:00-05:00</ShipDate>
                        <RevenueTotal>1222685.22</RevenueTotal>
                        <Average>150675.655000</Average>
                        - <Services>
                        <Date>2007-09-28T00:00:00-05:00</Date>
                        <Service>LSCA</Service>
                        <Shipments>218</Shipments>
                        <Revenue>47282.72</Revenue>
                        <Weight>299658</Weight>
                        </Services>
                        - <Services>
                        <Date>2007-09-28T00:00:00-05:00</Date>
                        <Service>DDD</Service>
                        <Shipments>3106</Shipments>
                        <Revenue>612732.30</Revenue>
                        <Weight>5694310</Weight>
                        </Services>
                        - <Services>
                        <Date>2007-09-28T00:00:00-05:00</Date>
                        <Service>CNSD</Service>
                        <Shipments>898</Shipments>
                        <Revenue>195894.04</Revenue>
                        <Weight>1650826</Weight>
                        </Services>
                        - <Services>
                        <Date>2007-09-28T00:00:00-05:00</Date>
                        <Service>FXCE</Service>
                        <Shipments>208</Shipments>
                        <Revenue>115753.72</Revenue>
                        <Weight>443930</Weight>
                        </Services>
                        - <Services>
                        <Date>2007-09-28T00:00:00-05:00</Date>
                        <Service>SMTP</Service>
                        <Shipments>52</Shipments>
                        <Revenue>2303.76</Revenue>
                        <Weight>15450</Weight>
                        </Services>
                        - <Services>
                        <Date>2007-09-28T00:00:00-05:00</Date>
                        <Service>USPS</Service>
                        <Shipments>188</Shipments>
                        <Revenue>46567.62</Revenue>
                        <Weight>333222</Weight>
                        </Services>
                        - <Services>
                        <Date>2007-09-28T00:00:00-05:00</Date>
                        <Service>FXH3</Service>
                        <Shipments>322</Shipments>
                        <Revenue>27305.04</Revenue>
                        <Weight>117464</Weight>
                        </Services>
                        - <Services>
                        <Date>2007-09-28T00:00:00-05:00</Date>
                        <Service>DTRL</Service>
                        <Shipments>1662</Shipments>
                        <Revenue>157566.04</Revenue>
                        <Weight>401446</Weight>
                        </Services>
                        </Days>
                        </NewDataSet>

                        I suspect my xml is correct...I really struggled getting it where it is here! Thanks again....you folks are great!

                        curtkauf
                        • 9. Re: Load web service into ArrayCollection
                          curtkauf Level 1
                          Tracy,

                          Thanks! How do you loop the an e4x result to build an ArrayCollection? Thanks!

                          Curt
                          • 10. Re: Load web service into ArrayCollection
                            ntsiii Level 3
                            Something like:
                            var xlServices:XMLList = xmlResult..Service;
                            var xmlService:XML;
                            for (var i:int=0,i<xlServices.length;i++) {
                            xmlService = xlServices ;
                            _acServices.addItem({Date:xmlService.Date.text(),Service:xmlService.Date.text()}); //the text() might not be necessary
                            }

                            Tracy
                            • 11. Re: Load web service into ArrayCollection
                              ntsiii Level 3
                              The forum ate the brackets:
                              xmlService = xlServices [ i ];
                              • 12. Re: Load web service into ArrayCollection
                                curtkauf Level 1
                                Tracy,

                                Thanks so much for your help. One question regarding ArrayCollection - XMLListCollection. I am creating webservices that need to return datasets. I'm doing this in .Net. I have always returned arrays, but as you can see have recently been trying XML. When should I use XML and when should I use arrays. What are the pros and cons of XMLListCollection and ArrayCollections. I would appreciate your input. Thanks!

                                Curt