0
//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!

1
  • 1
    That is not the exact problem in your case. Flash is a asynchronous. So it won't wait to execute second line until first line completes execution. Now you could guess trace(linksXML.*) executes before the loading event completes. The reason for null is linksXML is defined inside the load complete event function. Commented Sep 14, 2012 at 11:10

3 Answers 3

1

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);
}
Sign up to request clarification or add additional context in comments.

2 Comments

The complete handler calls processXML
What exactly should I do to make variable exist outside the function, because that is needed to make other functions work properly
0

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.

Comments

0

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!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.