PDA

View Full Version : XML loader class



bzouchir
August 5th, 2007, 10:29 PM
Hi everyone,

I'm just trying to write an XMLLoader class, that I can use over and over, and passing a string of the xml url to load.

the XMLLoader class is:


package classes
{
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLRequest;

public class XMLLoader extends Sprite
{
private var _xmlData:XML;
private var loader:URLLoader;

public function XMLLoader(xmlURL:String)
{
var xmlRequest:URLRequest = new URLRequest(xmlURL);
loader = new URLLoader (xmlRequest);
loader.addEventListener(Event.COMPLETE, onComplete);
trace("XML Loader init()");
}
private function onComplete(event:Event):void
{
_xmlData = XML(loader.data);
trace("xml is loaded");
}
public function get xmlData():XML
{
var _data:XML = _xmlData;
return _data;
}
}
}

the main class is XMLSetup :


package classes
{
import flash.display.Sprite;
import flash.events.Event;
public class XMLSetup extends Sprite
{
private var loader:XMLLoader;
private var xmlURL:String = "xml/test.xml";

public function XMLSetup()
{
init();
}
private function init():void
{
loader = new XMLLoader(xmlURL);
trace(loader.xmlData);
trace("XMLSetup init()");
}
}
}

now when I run a test it outputs:

XML Loader init()
null
XMLSetup init()
xml is loaded

so basically trace(loader.xmlData);
is being called before the xml is loaded; returning null.

what is the best way of fixing this? is there any event that I can fire for the main class to know that intance has loaded the xml? aor what is the best way to do this?

thanks

McGuffin
August 5th, 2007, 11:38 PM
XMLLoader class:



private function onComplete(event:Event):void {
_xmlData = XML(loader.data);
dispatchEvent(new Event(Event.COMPLETE));
trace("xml is loaded");
}


XMLSetup class:



private function init():void {
loader = new XMLLoader(xmlURL);
loader.addEventListener(Event.COMPLETE, onComplete);
function onComplete(e:Event):void {
trace(loader.xmlData);
}
trace("XMLSetup init()");
}


Make sure Event is imported into the XMLSetup class as well.

That should have you sorted. For the sake of having a perfect code, you'd do well to remove your loading code from the XMLLoader constructor and move it to a separate function, such as load(xmlURL:String), so that you can register your event listener before the loading has commenced. Your XMLSetup code would then look something like this:



loader = new XMLLoader();
loader.addEventListener(Event.COMPLETE, onComplete);
function onComplete(e:Event):void {
trace(loader.xmlData);
}

loader.load(xmlURL);


See my point? Anyway, best of luck mate :)

bzouchir
August 6th, 2007, 06:50 AM
cheers mate, worked like a charm!

I also did as suggested, called the load from a public method rather than the constructor, much more stable and better controlled this way!

thanks for the help :)

McGuffin
August 6th, 2007, 12:08 PM
No probs mate. Couple things I forgot to tie off (this is what you get when you're up late at night on Sunday!)

1. You should use removeEventListener's to get rid of those ties:

XMLSetup:


loader.addEventListener(Event.COMPLETE, onComplete);
function onComplete(e:Event):void {
loader.removeEventListener(Event.COMPLETE, onComplete);
trace(loader.xmlData);
}

loader.load(xmlURL);


So the same thing in XMLLoader with the onComplete function, should be exactly the same removeEventListener code.

2. You can tidy up your code slightly by removing the new XMLLoader(); declaration from the init() function and make it declare in the var section:



private var loader:XMLLoader = new XMLLoader();


This way you can use it outside the class (would need to change accessor to public, or use a getter function) knowing that it's already instantiated :)

bzouchir
August 7th, 2007, 03:52 AM
Done! Makes perfect sense :)

cheers mate for the info :pleased: