Antes de continuar, indicar que este post no contiene un ejemplo completo para poder probar, si no que explica detalladamente como resolver esta situación.
Tras dar vueltas y vueltas al problema, he realizado una pequeña "ñapa" o "parche" para que la carga del ArrayCollection se realice sin problemas.
En primer lugar voy a presentar el XML que devuelve el HTTPService:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<products_providers_in_use>
<product_provider_in_use>
<data>6</data>
<label>Bill Gates</label>
<id_product>21</id_product>
<name_product>Escalope de ternera</name_product>
<total>0</total>
</product_provider_in_use>
...
<products_providers_in_use>
La definición del HTTPService permite definir en qué funciones delegar la ejecución en caso de error (fault) o de éxito (result), así como la URL al HTTPService (url).
<!-- Call to srvGetProductsProvidersInUse service -->
<mx:HTTPService
result="handleProductsProvidersInUse(event);"
fault="handleFault(event);"
id="nombre_del_servicio" resultFormat="object"
url="url_al_httpservice"
useProxy="false">
</mx:HTTPService>
Es necesario definir el ArrayCollection como una variable de ámbito local, que pueda ser accedida por todas funciones del módulo, componente, etc.
[Bindable]
import mx.collections.ArrayCollection;
private var acInUse:ArrayCollection;
La llamada al HTTPService se realiza mediante el objeto HTTPService (referenciando el nombre indicado en la propiedad id) y al método "send" en el momento que sea necesario (en el creationComplete, al pulsar un botón, etc.):
nombre_del_servicio.send();
Una vez se ejecuta el HTTPService, éste accederá a dicho servicio para obtener un XML. En el caso de que no se haya producido ningún problema en la comunicación, se delegará la ejecución en la función definida en "result". El código para leer correctamente este XML en todos los casos (ya corregido el bug) es el siguiente:
private function handleProductsProvidersInUse(event:ResultEvent):void {
try {
acInUse =
event.result.products_providers_in_use.product_provider_in_use
as ArrayCollection;
}
catch (err:Error) {
acInUse=new ArrayCollection();
}
if (acInUse==null) {
var o:Object;
o=event.result.products_providers_in_use.product_provider_in_use;
acInUse = new ArrayCollection(
[{data:o.data,label:o.label,id_product:o.id_product,
name_product:o.name_product,total:o.total}]);
}
}
Para controlar las excepciones se abre un bloque try...catch para intentar acceder al XML recogido. Lo normal es asignar al ArrayCollection la colección de datos del XML que se repite. El XML está contenido dentro del parámetro de evento, y en la propiedad "result". El primer elemento del XML ("products_providers_in_use") no se repite, y marca el principio y fin del grupo de datos. Por ello hay que llegar hasta el siguiente nivel del XML: "product_provider_in_use". En teoría, este nivel retornaría un ArrayCollection. En el caso de que tenga más de un elemento no hay problema, pero si hay un sólo elemento, no produce ninguna excepción, pero, inexplicablemente, nos retorna un null. Por ello, tras el catch se hace una comprobación de si es nulo, en cuyo caso se crea un ArrayCollection nuevo, se recoge el único elemento del resultado en un objeto genérico, y se crea un elemento con la información recogida en el XML. En el caso de que el XML estuviera vacío o tuviera algún problema, saltaría una excepción, la cual es recogida por el bloque "catch" y crea un ArrayCollection nuevo, pero vacío, pero no null.
Espero que este ejemplo corte definitivamente el tiempo que os haya hecho perder esta singular situación.