7 Replies Latest reply on Sep 14, 2007 4:22 PM by sandy_zylka

    Can't populate a grid from results of web service

    sandy_zylka
      ************************************************************************
      The SOAP Body coming back from my Web Service looks like this:
      ************************************************************************
      <soap-env:Body>
      <FindCustomersResult xmlns=" http://www.nextaxiom.com/soapservice/xsd1">
      <Customer>
      <CustomerId>11</CustomerId>
      <FirstName>Gregory</FirstName>
      <LastName>Penn</LastName>
      </Customer>
      <Customer>
      <CustomerId>22</CustomerId>
      <FirstName>Sean</FirstName>
      <LastName>Smith</LastName>
      </Customer>
      </FindCustomersResult>
      </soap-env:Body>

      ************************************************************************
      My Web Service call from Flex Builder 2:
      ***********************************************************************
      <mx:WebService id="ws"
      wsdl=" http://SZYLKA6000:7777/NXAServer/NextAxiomServer?servicepath=StandardTraining.FindCustomer s"
      useProxy="false"
      showBusyCursor="true"
      fault="Alert.show(event.fault.faultString), 'Error'">
      <mx:operation name="FindCustomers" resultFormat="e4x" >
      <mx:request>
      <FindCustomers>
      <FilterBy>
      <LastName>{LastName.text}</LastName>
      <Country>{Country.text}</Country>
      </FilterBy>
      </FindCustomers>
      </mx:request>
      </mx:operation>
      </mx:WebService>

      ************************************************************************
      The Flex grid I'm trying to populate:
      ***********************************************************************
      <mx:DataGrid x="23" y="187" width="517" height="153"
      dataProvider="{ws.FindCustomers.lastResult.FindCustomersResult.Customer}" >
      <mx:columns>
      <mx:DataGridColumn headerText="Id" dataField="CustomerId" width="45"/>
      <mx:DataGridColumn headerText="First Name" dataField="FirstName"/>
      <mx:DataGridColumn headerText="Last Name" dataField="LastName"/>
      </mx:columns>
      </mx:DataGrid>

      ************************************************************************
      The problem:
      ************************************************************************
      My grid does not populate with data, and I get the following warnings from the debugger:
      warning: unable to bind to property 'FindCustomersResult' on class 'XMLList' (class is not an IEventDispatcher)
      warning: unable to bind to property 'Customer' on class 'XMLList' (class is not an IEventDispatcher)

      ************************************************************************
      Interesting Notes:
      ************************************************************************
      1) If I change the dataProvider value of the grid to the following:
      dataProvider="{ws.FindCustomers.lastResult.FindCustomersResult.Customer}"

      Then, then the grid appears to get populated with empty rows -- the scroll bar appears on the grid, and if I count the rows, it 's the 19 that I expect -- but the rows show no data)

      2) I can successfully retrieve and display the 2nd customer item, in a TextInput component like this:
      <mx:TextInput x="35" y="368" text="{ws.FindCustomers.lastResult.Customer[1].CustomerId}"/>

      AND like this (with two dots between last result and Customer):
      <mx:TextInput x="35" y="368" text="{ws.FindCustomers.lastResult..Customer[1].CustomerId}"/>

      BUT this does not work:
      <mx:TextInput x="35" y="368" text="{ws.FindCustomers.lastResult.FindCustomersResult.Customer[1].CustomerId}"/>


      3) I've tried populating an XMLListCollection and referencing that from the dataProvider, but doesn't work:

      <mx:XMLListCollection id="CustomerList"
      source="{ws.FindCustomers.lastResult.FindCustomersResult.Customer}" />

      4) I've tried populating an ArrayCollection and referencing that from the dataProvider, but doesn't work:
      <mx:ArrayCollection id="CustomerArray"
      source="{ArrayUtil.toArray(ws.FindCustomers.lastResult.FindCustomersResult.Customer}"/>

      5) I've tried adding XML definition to the data provider statement, but that doesn't work... although it seems to suppress the warning messages:

      dataProvider="{XML(ws.FindCustomers.lastResult).FindCustomersResult.Customer}"

      6) I've tried several other things as well. Someone who has knowledge please help, as I would like to recommend Flex and show this working to a customer that my company will be visiting next week.
      Thanks in Advance.
        • 1. Re: Can't populate a grid from results of web service
          jemiller0
          The following is how I'm doing it. In mine, I'm defining the web service in code. You can do it in markup too though. I'd get rid of the resultFormat="e4x". I think someone mentioned to me something about not being able to bind using e4x. I never used it, so, I don't know. Note, the Bindable attribute, tells it to detect changes to the collection and propagate the changes to the UI. I don't know if you have to do it that way, that's just the way I'm doing it.

          [Bindable]
          public var reservations : ArrayCollection = new ArrayCollection();

          public function this_initialize() : void {
          webService.loadWSDL("https://localhost:7443/ReservationsWebService/ReservationsWebService ?wsdl");
          webService.findReservations.addEventListener("result", webService_findReservations_result);
          }

          public function webService_findReservations_result(event : ResultEvent) : void {
          reservations = ArrayCollection(event.result);
          }

          <mx:DataGrid id="reservationsDataGrid" dataProvider="{reservations}">
          ...
          </mx:DataGrid>
          • 2. Re: Can't populate a grid from results of web service
            jemiller0 Level 1
            Note, you can set the event listener in markup too I think. I don't know the correct syntax offhand. Like I said, if you get rid of the e4x, you'll probably have better luck. Set a break point in the event handler for the result, then debug the app and switch to the Variables tab, and you can see the returned object graph and see how it looks.
            • 3. Re: Can't populate a grid from results of web service
              sandy_zylka Level 1
              Bless your heart... that worked! Thanks so much!

              I do have one question for you, though... in this case, I only had one list under the <FindCustomerResult> element. No where did I reference that I was interested in the list of <Customer> elements . What if I had had two element lists the <FindCustomerResult> element? How would it know which list to populate the array with?

              Thanks in advance.
              • 4. Re: Can't populate a grid from results of web service
                jemiller0 Level 1
                I think that FindCustomerResult is just a wrapper around all of the results that are returned from the web service method. In this case, on the server side, it's probably just returning a List or an array. If they returned a class, with multiple different lists in it, you would be able to drill down into the structure the same way you would any other property. Like I mentioned before, using the debugger is probably the best way to see what's going on because you can click on the tree of objects in memory and expand them out and see what the structure is.

                One other thing that is worth mentioning. Definitely install 2.0.1 hot fixes 2 and 3. There are major bugs fixed in them. I was having a lot of issues regarding collections not being deserialized correctly and the problems went away after upgrading to hot fix 3. Normally, I'm leary about installing hot fixes (I normally wait until they are solidified into a service pack), but, in this case it turned out to help a lot.
                • 5. Re: Can't populate a grid from results of web service
                  sandy_zylka Level 1
                  Thanks so much... I really appreciate all of your help.
                  • 6. Re: Can't populate a grid from results of web service
                    jemiller0 Level 1
                    No problem. One other problem to watch out for is that if you have a method that returns a collection, but, the collection only has one item, it just returns the one item instead of a collection with one item in it. Not sure what's up with that... Probably a bug as far as I know.
                    • 7. Re: Can't populate a grid from results of web service
                      sandy_zylka Level 1
                      I tried this out, but it worked well for me. I was able to retrieve and display a single customer item in the grid. Note that I don't have hotfix 2 or 3 installed... I had to uninstall them as I had a problem with the Web service request with the hotfixes).

                      I also created a new Web Service that returned both a list and a single integer field to see if that would work, but it doesn't. I'm using Doc/Literal style, so my web service can have multiple outputs under the <FindCustomersResult> element. My new web service returned a list of complex <Customer> elements and a simple <NumOrders> element. Since I have no way to reference the <Customer> list when I populate the ArrayCollection, it barfs on creation.

                      Oh well, now I know that this is a limitation -- if a Web service returns a complex list, that's all it can return -- unless I find some way to specifically reference the list I want in the SOAP (XML) response.