kamilosxd678
kamilosxd678

Reputation: 11

AS3 XML Loading - variable does not exist outside the loading function

//Generating menu from XML
var linksXML:XML;
var linksLoader:URLLoader = new URLLoader();
var linksDB:Array = new Array();
linksLoader.load(new URLRequest("menu_links.xml"));
linksLoader.addEventListener(Event.COMPLETE, processXML);
function processXML(evnt:Event):void {
    linksXML = new XML(evnt.target.data);
    for (var i:int = 0; i < linksXML.link.length(); i++){
        var newLink:Array = [linksXML.link[i].@name, linksXML.link[i].@param, linksXML.link[i]];
        linksDB[i] = new Array(newLink);
        trace(linksDB);
    }
}
trace(linksXML.*);

Output is

Second trace: 
null
First trace: 
<menu>
  <link name="first" param="true">first.php</link>
  <link name="second" param="true">second.php</link>
  <link name="third" param="true">third.php</link>
</menu>

So in my opinion flash is losing variable when exitin the function. Please help! I have no idea why this happens

Thanks in advance!

Upvotes: 0

Views: 480

Answers (3)

Ryan Hollingsworth
Ryan Hollingsworth

Reputation: 381

The title of the post suggest an issue of scope. It looks like you've defined the array outside of the function; however, I'm unsure if var linksDB:Array = new Array(); is the proper way to do it. Try var linksDB:Array = [];

Here's a simple XML loaded thing i put together a long time ago. the content isn't related to what you're doing, but felt a working example may be useful if you're like me :)

var xmlLoad = new URLLoader(xmlLocation);
xmlLoad.addEventListener(Event.COMPLETE, buildSlider);

function buildSlider(e){

    var adList = new XML(e.target.data);
    numPics = adList.ad.length();

    for(var i in adList.ad){
        var pic = new Pic;
        pic.pic = adList.ad[i].pic;
        pic.clicky = adList.ad[i].clicky;
        pic.init();
        pic.x = picWidth * i;       
        contentHolder.addChild(pic);
    }   
    endChecker();

    // autoplay until end of list, or until user clicks
    autoInterval = setInterval(nextButtClick, 4000);
}

XML:

<?xml version="1.0" encoding="UTF-8"?>
<ads>

    <ad>
        <pic>40-Hinton-Gardens.jpg</pic>
        <clicky>http://corderhomes.com</clicky>
    </ad>

    <ad>
        <pic>644-Haymarket-Lane.jpg</pic>
        <clicky>http://corderhomes.com</clicky>
    </ad>

    <ad>
        <pic>756-Cambridge-Lane.jpg</pic>
        <clicky>http://corderhomes.com</clicky>
    </ad>

    <ad>
        <pic>9809-Charolais-Drive.jpg</pic>
        <clicky>http://corderhomes.com</clicky>
    </ad>


</ads>

Hopefully that helps a little :) Good luck!

Upvotes: 0

Benny
Benny

Reputation: 2228

XML data has been stored in linksXML variable only when the Event.COMPLETE handler complete its task because as3 is asynchronous. Trace the linksXML var within the processXML function.

Edit:

function processXML(e:Event):void{
        .....
        .....
    futureAction();
}
function futureAction():void{
     trace(linksXML);
}

Upvotes: 1

George Profenza
George Profenza

Reputation: 51837

Actually it does exist, it's just not initialized when you trace it outside of the handler. Imagine the code a bit like this:

  1. initialize variables
  2. load xml
  3. set a load complete handler for the xml loader
  4. trace xml

I've omitted processXML because even though you define it above

trace(linksXML.*);

it doesn't mean it gets called there, it is an asynchronous function that gets called when the URLLoader finished loading. You're tracing the xml immediately after loading and therefore, at that point in time, the xml will not be ready.

It if helps, try this:

var linksXML:XML;
var linksLoader:URLLoader = new URLLoader();
var linksDB:Array = [];
linksLoader.load(new URLRequest("menu_links.xml"));
linksLoader.addEventListener(Event.COMPLETE, processXML);
function processXML(evnt:Event):void {
    linksXML = new XML(evnt.target.data);
    for (var i:int = 0; i < linksXML.link.length(); i++){
        linksDB[i] = [linksXML.link[i].@name, linksXML.link[i].@param, linksXML.link[i]];
        trace(new Date() + " xml parsed: \n"+linksDB);
    }
}
addEventListener(Event.ENTER_FRAME,checkXML);
function checkXML(event:Event):void{
    trace(new Date(),linksXML);
    if(linksXML != null) removeEventListener(Event.ENTER_FRAME,checkXML);
}

It should make it easier to see what happens to the xml. Of course, you will simply trigger other actions that rely on that XML in processXML, you wouldn't need the ENTER_FRAME handler, it's there just to illustrate a point.

In short, the variable is accesible outside the function, it's just it doesn't have a value until processXML gets called. After that point, it's ready. Feel free to use a debugger also if it helps.

Upvotes: 0

Related Questions