views:

255

answers:

1

I'm trying to parse an XML file and create an object array from its data. The data is converted to MediaAlbum classes (class of my own). The XML is parsed correctly and the object is loaded, but when I instantiate it, the Albums array is of zero length, even when the data is loaded correctly.

I don't really know what the problem could be... any hints?

import Nem.Media.*;
var mg:MediaGallery = new MediaGallery("test.xml");
trace(mg.Albums.length);

MediaGallery class:

package Nem.Media
{
    import flash.net.URLRequest;
    import flash.net.URLLoader;
    import flash.events.*;

    public class MediaGallery
    {
        private var jsonGalleryData:Object;
        public var Albums:Array = new Array();

        public function MediaGallery(xmlSource:String)
        {
            var loader:URLLoader = new URLLoader();
            loader.load(new URLRequest(xmlSource));

            loader.addEventListener(Event.COMPLETE, loadGalleries);
        }

        public function loadGalleries(e:Event):void
        {
            var xmlData:XML = new XML(e.target.data);
            var album;

            for each (album in xmlData.albums)
            {
                Albums.push(new MediaAlbum(album.attribute("name"), album.photos));
            }
        }
    }
}

XML test source:

<gallery>
    <albums>
        <album name="Fútbol 9">
            <photos>
                <photo width="600" height="400" filename="foto1.jpg" />
                <photo width="600" height="400" filename="foto2.jpg" />
                <photo width="600" height="400" filename="foto3.jpg" />
            </photos>
        </album>
        <album name="Fútbol 8">
            <photos>
                <photo width="600" height="400" filename="foto4.jpg" />
                <photo width="600" height="400" filename="foto5.jpg" />
                <photo width="600" height="400" filename="foto6.jpg" />
            </photos>
        </album>
    </albums>
</gallery>

Solved

Added callback function to constructor to handle XML data once loading is completed.

+2  A: 

The problem here is that you are creating the MediaGallery object which is parsing the xml and then checking the size of the parsed data before it is ready. I would recommend using a callback function. To do this you need only alter your MediaGallery constructor as shown.

private var callbackObj:Object;

public function MediaGallery(xmlSource:String, callback:Object)
    {
        var loader:URLLoader = new URLLoader();
        loader.load(new URLRequest(xmlSource));

        loader.addEventListener(Event.COMPLETE, loadGalleries);
        this.callbackObj = callback;
    }

Now you need an update method in the class that instantiates MediaGallery, such as:

public function update():void {
    trace(mg.Albums.length);
}

Finally, all you need to do is add a call to the update method in your Event.Complete handler. (Alter it in the following way).

public function loadGalleries(e:Event):void
    {
        var xmlData:XML = new XML(e.target.data);
        var album;

        for each (album in xmlData.albums)
        {
            Albums.push(new MediaAlbum(album.attribute("name"), album.photos));
        }

        this.callbackObj.update();
    }

This should solve your problem :-D Just remember, when you are dealing with a URLLoader, you need to write your code so it is event driven or you will be trying to utilize data that has not been retrieved yet.

Good Luck

Matt
I've made it work by changing the callbackObj into a function and then using `callbackObj.call(this)`. Thanks for the tip Matt!
Joel Alejandro