views:

634

answers:

2

I'm a C# developer who is trying to learn some AS3, so this is going to be a pretty newbie question.

I'm getting confused with regards to scope and GC, as I have a custom MovieClip-extending class (Slide) which I create instances of within a loop and push() into an Array, but afterwards the items are null when I pull them out of the collection.

var ldr:URLLoader = new URLLoader();
ldr.load(new URLRequest("presentation.xml"));
ldr.addEventListener(
 Event.COMPLETE,
  function(e:Event):void {
   config = new XML(e.target.data);
   for (var i:Number = 0; i < config.slides.slide.length(); i++)
   {
    var node = config.slides.slide[i];
    var slide:Slide = new Slide();       
    slides.push(slide);

    addChild(slide); // Works fine
   }
  }
);

slides.forEach(function(e:*, index:int, array:Array):void
 {
  addChild(e); // Causes "Parameter child must be non-null" exception
 }
);

I would like to be able to references the slides later in order to toggle them as needed - how can I keep the reference to my new objects?

Update: It appears there were two problems with this. The forEach call was being made before the URLLoader's complete event was called, and also forEach doesn't seem to work as expected. Here is the final working code:

var ldr:URLLoader = new URLLoader();
ldr.load(new URLRequest("presentation.xml"));
ldr.addEventListener(
    Event.COMPLETE,
    function(e:Event):void {
     config = new XML(e.target.data);
     for (var i:Number = 0; i < config.slides.slide.length(); i++)
     {
      var node = config.slides.slide[i];
      var slide:Slide = new Slide();                      
      slides.push(slide);
     }
     for each (var sl in slides)
     {
      addChild(sl);
     }
    }
);
+3  A: 

Your slides.forEach call is executing before the event is being fired so the slides array has no values.

Richard Szalay
Doh, of course it is! I need to stop thinking C# and start thinking jQuery...
tags2k
Ah, but why am I being sent null items? Surely if the array is empty it should pass me nothing?
tags2k
I've now tried moving the forEach into the event callback and it still doesn't work :(
tags2k
Are u calling load AFTER you add the listener?
ozke
Tried that too, no luck!
tags2k
Have you tried doing a manual foreach(var slide : Slide in slides) {} rather than using .forEach?
Richard Szalay
Thanks Richard, that was it, except that syntax didn't work but for each (var slide in slides) {} did.
tags2k
So I guess my answer worked then? (just to know)
ozke
Sorry, my c# brain was in gear ;) Glad to have helped.
Richard Szalay
+1  A: 

Try this. Let's see if it traces your slides.

var ldr:URLLoader = new URLLoader();
ldr.addEventListener(Event.COMPLETE, processXML);
ldr.load(new URLRequest("presentation.xml"));

function processXML(e:Event):void {
    config = new XML(e.target.data);
    var slide:Slide;
    for (var i:Number = 0; i < config.slides.slide.length(); i++)
    {
        var node = config.slides.slide[i];
        slide = new Slide();                                          
        slides.push(slide);

        addChild(slide); // Works fine
    }

    for each(var slide:Slide in slides){
        trace(slide);
    }
 }

I am coding it here so I can't assure you it'll work. Also, I don't have the rest of the code so you'll have to test it by yourself.

ozke
Put a "var" in before the "slide in slides" and I'll mark you as the answer!
tags2k
Done. Sorry, it's what happens when you try to improvise coding! :P
ozke