6 Replies Latest reply on Jan 16, 2007 6:30 AM by kisetta

    XML generation problem?

    kisetta
      Hi I'm relatively new to Flex 2 and I have a question.

      I'm generating an xml file from an oracle view and hope to use it as the basis for a chart/data grid.

      My generation process yields data something like this:
      <list>
      <commodity name="Laptop Computer" total="0">
      <warehouse name="California" onhand="10"/>
      <warehouse name="Viriginia" onhand="20"/>
      <warehouse name="Washington" onhand="0"/>
      </commodity>
      <commodity name="Desktop Computer" total="0">
      <warehouse name="Washington" onhand="9"/>
      </commodity>
      </list>

      I've taken this generated xml and put it into a local file for now.

      When I attempt to load this data I get this error:
      TypeError: Error #1009: Cannot access a property or method of a null object reference.
      at TestFileAccess/TestFileAccess::resultHandler()
      at TestFileAccess/__srv_result()
      at flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEventFunction()
      at flash.events::EventDispatcher/dispatchEvent()
      ...
      at flash.net::URLLoader/flash.net:URLLoader::onComplete()

      My mxml file looks something like this:
      <?xml version="1.0" encoding="utf-8"?>
      <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" layout="absolute" xmlns="*" paddingTop="3" creationComplete="initApp()" pageTitle="Warehouse Levels">
      <mx:Script>
      <![CDATA[
      import mx.collections.ArrayCollection;
      import mx.rpc.events.*;
      [Bindable]
      private var commodData:Array;
      [Bindable]
      private var warehouseData:Array;
      [Bindable]
      public var slicedCommodData:ArrayCollection;

      private function initApp():void
      {
      srv.send();
      slicedCommodData = new ArrayCollection();
      }
      private function resultHandler(event:ResultEvent):void
      {
      commodData = event.result.list.name.source as Array;
      warehouseData = new Array(commodData.length);
      slicedCommodData.source = commodData;

      var commodTotal:Number;
      for (var x:Number = 0; x < commodData.length; x++)
      {
      warehouseData[x] = {name: commodData[x].name, onhand:0};
      var warehouses:Array = commodData[x].warehouse.source as Array;
      commodTotal = 0;
      for (var j:Number = 0; j < warehouses.length; j++)
      {
      commodTotal += warehouses[j].onhand;
      }
      commodData[x].total = commodTotal;
      }
      }
      ]]>
      </mx:Script>
      <mx:HTTPService id="srv" url="result.xml" useProxy="false" result="resultHandler(event)"/>
      <mx:Panel layout="absolute">
      <mx:ColumnChart id="WarehouseTotals" dataProvider="{slicedCommodData.source}">
      <mx:horizontalAxis>
      <mx:CategoryAxis dataProvider="{slicedCommodData.source}" categoryField="Name"/>
      </mx:horizontalAxis>
      <mx:series>
      <mx:ColumnSeries xField="Name" yField="Total"/>
      </mx:series>
      </mx:ColumnChart>

      <mx:DataGrid dataProvider="{slicedCommodData.source}">
      <mx:columns>
      <mx:DataGridColumn headerText="Commodity" dataField="Name"/>
      <mx:DataGridColumn headerText="Total" dataField="Total"/>
      </mx:columns>
      </mx:DataGrid>
      </mx:Panel>
      </mx:Application>

      I'm wondering if something is wrong with my generated xml data or if its something else. I did notice that my xml generation doesn't always produce 3 warehouse tags for every commodity. Could this be the problem?
      Also, the reason the commodity tag's total is always 0 in the xml is because this information is not captured in the view...I use mxml to calculate that.

      Thanks!
        • 1. Re: XML generation problem?
          peterent Level 2
          First, you should not use the .source property of a collection in data-binding. It defeats the purpose because the source (an Array for ArrayCollection) does not implement any of the data binding code. Where you have:

          dataProvider="{slicedCommodData.source}" change it to dataProvider="{slicedCommodData}"

          Second, you have your HTTPService going after an XML file. But in your result handler you are treating the data as if it were an array: commodData = event.result.list.name.source as Array; The result is not an array, it is XML. Try something like this:

          [Bindable] var commodData:XMLList;
          [Bindable] var slicedCommodData:XMLListCollection;

          Then in your result handler:

          commodData = event.result.commodity;

          With your data, event.result IS the XML document. event.result.commodity is an XMLList of all the <commodity> nodes in the XML document.

          • 2. Re: XML generation problem?
            kisetta Level 1
            Ok I made those changes. But now I'm getting that same error on a line in my resultHandler() function. It seems to have a problem with commodData.length. When I use the debugger it says that commodData is null.

            I've bolded the line its complaining about and only included the relevant code this time around:
            [Bindable]
            private var commodData:XMLList;

            [Bindable]
            public var slicedCommodData:XMLListCollection;

            private function initApp():void
            {
            srv.send();
            slicedCommodData = new XMLListCollection();
            }
            private function resultHandler(event:ResultEvent):void
            {
            commodData = event.result.commodity;
            slicedCommodData.source = commodData;

            var commodTotal:Number;
            for (var x:Number = 0; x < commodData.length; x++)
            {
            var warehouses:XMLList = commodData[x].warehouse as XMLList;
            commodTotal = 0;
            for (var j:Number = 0; j < warehouses.length; j++)
            {
            commodTotal += warehouses[j].onhand[j];
            }
            commodData[x].total[x] = commodTotal;
            }
            }
            Am I supposed to have something else in here?
            • 3. Re: XML generation problem?
              kisetta Level 1
              Actually scratch the above response. Sorry commodData is not null. I'm getting the data back just fine.

              I'm just still getting the same error:
              TypeError: Error #1009: Cannot access a property or method of a null object reference.
              at TestFileAccess/TestFileAccess::resultHandler()
              at TestFileAccess/__srv_result()
              at flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEventFunction()
              at flash.events::EventDispatcher/dispatchEvent()
              ...
              at flash.net::URLLoader/flash.net:URLLoader::onComplete()
              • 4. Re: XML generation problem?
                peterent Level 2
                2 problems: XMLList does not have a length property, it has a length() function:

                x < commodData.length();

                Second: slicedCommodData has to be allocated, you just can't set the source as they object doesn't exist:

                slicedCommodData = new XMLListCollection( commodData );
                • 5. Re: XML generation problem?
                  kisetta Level 1
                  Ok I made those changes and am still getting the same 1009 error. I also took out alot of my code. Now I'm just displaying it to a simple data grid. As of right now it fires the 1009 error and my datagrid comes back empty. So I'm still wondering if its my generated xml or something in my resultHandler function.

                  Here is the current state of the code (fixed a few other problems with it). The xml data is still the same.

                  <?xml version="1.0" encoding="utf-8"?>
                  <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" xmlns="*" paddingTop="3" creationComplete="initApp()" pageTitle="Warehouse Levels">
                  <mx:Script>
                  <![CDATA[
                  import mx.collections.XMLListCollection;
                  import mx.collections.IViewCursor;
                  import mx.rpc.events.*;
                  [Bindable]
                  private var commodData:XMLList;
                  [Bindable]
                  public var slicedCommodData:XMLListCollection;
                  private function initApp():void
                  {
                  srv.send();
                  }
                  private function resultHandler(event:ResultEvent):void
                  {
                  commodData = event.result.commodity;
                  slicedCommodData = new XMLListCollection(commodData);
                  var commodTotal:Number;
                  var nextNum:Number;
                  for (var x:Number = 0; x < commodData.length(); x++)
                  {
                  var warehouses:XMLList = commodData[x].warehouse as XMLList;
                  commodTotal = 0;
                  for (var j:Number = 0; j < warehouses.length(); j++)
                  {
                  nextNum = 0;
                  nextNum = new Number(warehouses[j].onhand[j]);
                  commodTotal = commodTotal + nextNum;
                  }
                  var myCursor:IViewCursor = slicedCommodData.createCursor();
                  var firstItem:Object = slicedCommodData.getItemAt(x);
                  var firstItemFromCursor:Object = myCursor.current;
                  myCursor.current.total = commodTotal;
                  }
                  }
                  ]]>
                  </mx:Script>
                  <mx:HTTPService id="srv" url="result.xml" useProxy="false" result="resultHandler(event)"/>
                  <mx:HDividedBox width="100%" height="100%">
                  <mx:DataGrid dataProvider="{slicedCommodData}">
                  <mx:columns>
                  <mx:DataGridColumn headerText="Commodity" dataField="@name"/>
                  <mx:DataGridColumn headerText="Total" dataField="@total"/>
                  </mx:columns>
                  </mx:DataGrid>
                  </mx:HDividedBox>
                  </mx:Application>

                  Thank you for your help!
                  • 6. Re: XML generation problem?
                    kisetta Level 1
                    It seems that I played with it for a while and fixed it. The problem was my xml data and the format my httpservice was returning. First my xml data needed to be enclosed by <data> and </data> tags not <list> and </list> tags. Second my httpservice needed to have a result format of e4x. This also caused me to have to change how I was handling the individual xml properties of the data.

                    Anyway the fixed code looks like this for anyone that cares and has gotten a similar error.
                    <?xml version="1.0" encoding="utf-8"?>
                    <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" xmlns="*" paddingTop="3" creationComplete="initApp()" pageTitle="Warehouse Levels">
                    <mx:Script>
                    <![CDATA[
                    import mx.collections.XMLListCollection;
                    import mx.rpc.events.*;
                    [Bindable]
                    private var commodData:XMLList;
                    [Bindable]
                    public var slicedCommodData:XMLListCollection;
                    private function initApp():void
                    {
                    srv.send();
                    }
                    private function resultHandler(event:ResultEvent):void
                    {
                    commodData = event.result.commodity;
                    slicedCommodData = new XMLListCollection(commodData);
                    var commodTotal:Number;
                    var nextNum:Number;
                    for (var x:Number = 0; x < commodData.length(); x++)
                    {
                    var warehouses:XMLList = commodData[x].warehouse as XMLList;
                    commodTotal = 0;
                    for (var j:Number = 0; j < warehouses.length(); j++)
                    {
                    nextNum = 0;
                    nextNum = new Number(warehouses[j].@onhand);
                    commodTotal = commodTotal + nextNum;
                    }
                    var firstItem:Object = slicedCommodData.getItemAt(i);
                    firstItem.@total = commodTotal;
                    }
                    }
                    ]]>
                    </mx:Script>
                    <mx:HTTPService id="srv" url="result.xml" resultFormat="e4x" result="resultHandler(event)"/>
                    <mx:HDividedBox width="50%" height="100%">
                    <mx:ColumnChart id="WarehouseTotals" dataProvider="{slicedCommodData}">
                    <mx:horizontalAxis>
                    <mx:CategoryAxis dataProvider="{slicedCommodData}" categoryField="@name"/>
                    </mx:horizontalAxis>
                    <mx:series>
                    <mx:ColumnSeries xField="@name" yField="@total"/>
                    </mx:series>
                    </mx:ColumnChart>
                    </mx:HDividedBox>
                    <mx:HDividedBox width="50%" height="100%">
                    <mx:DataGrid dataProvider="{slicedCommodData}">
                    <mx:columns>
                    <mx:DataGridColumn headerText="Commodity" dataField="@name"/>
                    <mx:DataGridColumn headerText="Total" dataField="@total"/>
                    </mx:columns>
                    </mx:DataGrid>
                    </mx:HDividedBox>
                    </mx:Application>

                    Thanks for all of your help!