2 Replies Latest reply on Apr 21, 2008 1:14 PM by dan19460

    ComboBox and e4x dataProvider labelField

    dan19460
      Okay, this should be a common use case but, of course, I am struggling with it. I simply want to populate a mx:ComboBox from the result of a Webservice but I am having trouble getting the ComboBox to pick up the appropriate xml for the labelField. The result of the Webservice call is e4x. The result of the Webservice (verified) is:

      <SOAP-ENV:Envelope xmlns:SOAP-ENV=" http://schemas.xmlsoap.org/soap/envelope/">
      <SOAP-ENV:Header/>
      <SOAP-ENV:Body>
      <mb:MarketBasketsResponse xmlns:mb=" http://mycompany.com/market-basket/schemas">
      <mb:MarketBasket basketId="1">
      <mb:Name>Client A</mb:Name>
      </mb:MarketBasket>
      <mb:MarketBasket basketId="2">
      <mb:Name>Client B</mb:Name>
      </mb:MarketBasket>
      </mb:MarketBasketsResponse>
      </SOAP-ENV:Body>
      </SOAP-ENV:Envelope>

      (note the namespace)

      In my webservice callback result handler :

      private function handleMarketBasketsResult(event:ResultEvent):void {
      var x:XML = new XML(event.result);
      namespace mb = " http://mycompany.com/market-basket/schemas";
      x.addNamespace(mb);
      mbCombo.dataProvider = x..mb::MarketBasket as XMLList;
      mbCombo.data = "mb::basketId";
      mbCombo.labelField = "mb::Name";
      }

      Unfortunately, the combo box gets populated with the entire XML string beginning with the MarketBasket elements (making for a big combo box!).

      This has to be a simple error on my behalf but I'm exhausted trying to find the answer. Is there someplace in the LiveDocs that points out a similar usage scenario?

      Thanks.

      Dan


        • 1. Re: ComboBox and e4x dataProvider labelField
          dan19460 Level 1
          Upon further research, the problem is the Namespace. It seems that you cannot use a namespace prefix in the labelField attribute of a mx:ComboBox. I was able to get the label set correctly in the combo by using a labelFunction instead of setting the labelField:

          private function getMarketBasketName(data:Object):String {
          return data.mb::Name;
          }

          My Webservice event handler callback now looks like this:

          private function handleMarketBasketsResult(event:ResultEvent):void {
          mbCombo.dataProvider = event.result.mb::MarketBasket;
          }

          Note that "mb" is now defined (scoped) as a module Namespace variable since I'm using it in multiple functions. Also, I do not set any labelField property of the combo since I've defined a labelFunction of "getMarketBasketName".

          I've also noted a similar phenomenon with binding a DataGrid to an XML type that contains a Namespace. To get values to appear in the columns, I've had to write labelFunctions for every column. Yuk!!! There may be a way to do this with a single function if you follow a convention or do something with string replacement but....

          Unless someone posts an alternative technique, the lesson I have learned is always convert an XML data type to an object (using manual or automated serialization) and bind the data controls to that object (or array of objects) instead of directly to the XML. It will save the headaches of writing all these little functions to deal with namespaces.



          • 2. Re: ComboBox and e4x dataProvider labelField
            dan19460 Level 1
            Just to complete the loop (BTW, I feel like I'm talking to myself)... Here is a function that you could use to dynamically extract the label from a child node with a namespace declaration. Note that this is only necessary with namespaces as I haven't had any trouble populating a data grid based upon the standard dataField attribute of the DataGridColumn otherwise. In this example, I use the setting of the dataField attribute (WITHOUT ANY REFERENCE TO NAMESPACES) passed into a function defined as the labelFunction for each column:

            private function getItemValue(data:Object, column:DataGridColumn):String {
            return data.child(new QName(mb, column.dataField));
            }

            I hope this saves others some of the aggravation I experienced on the issue. I'd still like to see a cleaner handling of namespaces in flex components but at least this works.

            Dan