7 Replies Latest reply on Aug 13, 2006 7:14 PM by isml

    I think there may be a Bug in the resultFormat of HttpService

    isml Level 1
      I'm sorry that no one gave me an advice on a Topic about HttpService ResultFormat that I posted several days ago. Maybe it is because I did not express myself well. And after many tests, the problem became even worse, as I found an example given in Doc had the same error.
      The Path: Flex 2 Developer's Guide > Data Access and Interconnectivity > Using RPC Components > Calling a service > Using parameter binding

      <?xml version="1.0"?>
      <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" verticalGap="20">
      <mx:Script>
      <![CDATA[
      import mx.utils.ArrayUtil;
      ]]>
      </mx:Script>

      <mx:HTTPService
      id="employeeSrv"
      url="employees.jsp">
      <mx:request>
      <deptId>{dept.selectedItem.data}</deptId>
      </mx:request>
      </mx:HTTPService>
      <mx:ArrayCollection
      id="employeeAC"
      source=
      "{ArrayUtil.toArray(employeeSrv.lastResult.employees.employee)}"/>
      <mx:HBox>
      <mx:Label text="Select a department:"/>
      <mx:ComboBox id="dept" width="150">
      <mx:dataProvider>
      <mx:ArrayCollection>
      <mx:source>
      <mx:Object label="Engineering" data="ENG"/>
      <mx:Object label="Product Management" data="PM"/>
      <mx:Object label="Marketing" data="MKT"/>
      </mx:source>
      </mx:ArrayCollection>
      </mx:dataProvider>
      </mx:ComboBox>
      <mx:Button label="Get Employee List" click="employeeSrv.send();"/>
      </mx:HBox>
      <mx:DataGrid dataProvider="{employeeAC}"
      width="100%">
      <mx:columns>
      <mx:DataGridColumn dataField="name" headerText="Name"/>
      <mx:DataGridColumn dataField="phone" headerText="Phone"/>
      <mx:DataGridColumn dataField="email" headerText="Email"/>
      </mx:columns>
      </mx:DataGrid>
      </mx:Application>

      In this example, if there is only one employee, it works well. As ArrayUtily.toArray() method has converted the object to an Array, but if there are two employees, problem comes out. I can only see a blank row in the DataGrid. And I watched the Length of returned Array of ArrayUtility.toArray(), it is 1, not 2. It is strange here. As ArrayUtily.toArray() should return the same Array if i pass a array to it. So I begin to doubt the return type of employeeSrv.lastResult.employees.employee is not a array. It is very easy to test, i just assign it to an array, and i received an error, which means i can not convert an ArrayCollection to an Array.

      So I got it. If there is only one employee, the return type is Object, if two, it is ArrayCollection.
      And what's the solution?

      Thanks in advance.
        • 1. Re: I think there may be a Bug in the resultFormat of HttpService
          peterent Level 2
          I'm afraid you are going to have to test the data type of the result and then decide what to do. If the data type is ArrayCollection, do nothing, just use the value. If the data type is not an ArrayCollection, use ArrayUtil to make an Array, then create a new ArrayCollection from the new Array or do: new ArrayCollection( [ result_here ] );

          We cannot automatically take a scalar result and convert it to any Array - it may be that the result is intended to be scalar. We've automatically converted an array into ArrayCollection is a convenience - which it is most of the time.
          • 2. Re: I think there may be a Bug in the resultFormat of HttpService
            isml Level 1
            Thanks for your reply most sincerely.
            Actually, I did have tried to test the data type of the result. But I still can not get it around.

            I know from the Docs about Type Detection that now "is" function is recommended and "typeof" or "instanceof" has been deprecated.
            Talk about the preceding example, and suppose there are two employees, so the return type is ArrayCollection, I code like the following:

            Alert.show((employeeSrv.lastResult.employees.employee is ArrayCollection).toString());

            and as Object is the base class, I even tested like this:
            Alert.show((employeeSrv.lastResult.employees.employee is Object).toString());

            But not a line showed "true".

            How should I code?

            Thanks again.


            • 3. Re: I think there may be a Bug in the resultFormat of HttpService
              peterent Level 2
              Let's suppose you are trying to store the result of the data service call in var employeeList:ArrayCollection. Try this in your result handler:

              if( employeeSrv.lastResult.employees is ArrayCollection ) {
              employeeList = employeeSrv.lastResult.employees; // all set, nothing to do
              } else {
              employeeList = new ArrayCollection( [ employeeSrv.lastResult.employees ] );
              }

              • 4. Re: I think there may be a Bug in the resultFormat of HttpService
                isml Level 1
                Thanks for your codes. But I'm sorry I still could not work it out. Maybe I am too stupid.
                The Data I tested is just from the Docs:
                <employees>
                <employee>
                <name>John Doe</name>
                <phone>555-777-66555</phone>
                <email>jdoe@fictitious.com</email>
                <active>true</active>
                </employee>
                <employee>
                <name>Jane Doe</name>
                <phone>555-777-66555</phone>
                <email>jndoe@fictitious.com</email>
                <active>true</active>
                </employee>
                </employees>

                Maybe I have made a silly mistake here. But it seems that the condition statement "employeeSrv.lastResult.employees is ArrayCollection " never return true.

                Thanks anyway.
                • 5. Re: I think there may be a Bug in the resultFormat of HttpService
                  peterent Level 2
                  Don't give up so easily. Instead of using lastResult of the event, use result.

                  Failing that, if you are using Flex Builder 2, set a breakpoint in the result handler, then examine the event variable. if possible, copy what you see and post it here.
                  • 6. Re: I think there may be a Bug in the resultFormat of HttpService
                    peterent Level 2
                    Here are a couple of other things to try:

                    Make sure have

                    import mx.collections.ArrayCollection;

                    Then try if( event.result is Array ) instead of is ArrayCollection.
                    • 7. I think there may be a Bug in the resultFormat of HttpService
                      isml Level 1
                      Thanks for the tremendous encouragement and help i received from you. Thanks you for your time and patience.
                      Actually, I'm ashamed to say that i still have not got it over. But never mind, as I have found if I specify the resultFormat of HTTPService to "e4x", I do not need to do any special work. I mean no matter how many employees there are in the httpservice result, it could work beautifully.
                      But it's a pity that i still do not know where i am wrong in my original codes. So if you could have a look at my test codes at your leisure, i would deeply appreciate your help.

                      <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" verticalGap="20">
                      <mx:Script>
                      <![CDATA[

                      import mx.controls.Alert;
                      import mx.collections.ArrayCollection;

                      private function HandleResult():void
                      {
                      var employeeList:ArrayCollection;
                      if(employeeSrv.lastResult.employees is Array)
                      {
                      Alert.show("It is an Array");
                      employeeList = employeeSrv.lastResult.employees;
                      }
                      else
                      {
                      Alert.show("It is an Object");
                      employeeList = new ArrayCollection([employeeSrv.lastResult.employees]);
                      }

                      dgTest.dataProvider = employeeList;
                      }
                      ]]>
                      </mx:Script>

                      <mx:HTTPService
                      id="employeeSrv"
                      url="employees.xml" result="HandleResult()">
                      <mx:request>
                      <deptId>{dept.selectedItem.data}</deptId>
                      </mx:request>
                      </mx:HTTPService>

                      <mx:HBox>
                      <mx:Label text="Select a department:"/>
                      <mx:ComboBox id="dept" width="150">
                      <mx:dataProvider>
                      <mx:ArrayCollection>
                      <mx:source>
                      <mx:Object label="Engineering" data="ENG"/>
                      <mx:Object label="Product Management" data="PM"/>
                      <mx:Object label="Marketing" data="MKT"/>
                      </mx:source>
                      </mx:ArrayCollection>
                      </mx:dataProvider>
                      </mx:ComboBox>
                      <mx:Button label="Get Employee List" click="employeeSrv.send();"/>
                      </mx:HBox>
                      <mx:DataGrid id="dgTest"
                      width="100%">
                      <mx:columns>
                      <mx:DataGridColumn dataField="name" headerText="Name"/>
                      <mx:DataGridColumn dataField="phone" headerText="Phone"/>
                      <mx:DataGridColumn dataField="email" headerText="Email"/>
                      </mx:columns>
                      </mx:DataGrid>
                      </mx:Application>

                      employees.xml
                      <employees>
                      <employee>
                      <name>John Doe</name>
                      <phone>555-777-66555</phone>
                      <email>jdoe@fictitious.com</email>
                      <active>true</active>
                      </employee>
                      <employee>
                      <name>Jane Doe</name>
                      <phone>555-777-66555</phone>
                      <email>jndoe@fictitious.com</email>
                      <active>true</active>
                      </employee>
                      </employees>