Home > flex > Why some AS3 swfs work stand alone but fail to load into other swfs

Why some AS3 swfs work stand alone but fail to load into other swfs

Most developers who create standalone swfs have some standard instantiation code in their class constructor, something like this:

stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;

This works fine when the swf is embedded on a page directly as the “stage” property will be available instantaneously.
When this swf is loaded into another swf however, say like this:

var loader:Loader = new Loader();
addChild(loader);
loader.load(new URLRequest("http://widget.meebo.com/mcr.swf?id=RQYRkTseLc"));

It generates the infamous and ambiguous: TypeError: Error #1009: Cannot access a property or method of a null object reference.
I’m pretty sure this is because when a swf is loaded into another swf, it’s class constructor is called to create the object before it is even added to it’s parent (the Loader object).
Thus the stage property is undefined, which throws the error, which kills the call stack including what ever else was in the constructor after the stage reference.
I’d kind of consider this a bug in the flash architecture.

The work around to insure your swf is compatible with loading into other swfs:
If the stage references are just the above, you can throw a try/catch around them as they would probably get set by the loader anyways:

try {
   stage.align = StageAlign.TOP_LEFT;
   stage.scaleMode = StageScaleMode.NO_SCALE;
} catch(er:Error) { };

or just ensure the property is available:

if (stage){
   stage.align = StageAlign.TOP_LEFT;
   stage.scaleMode = StageScaleMode.NO_SCALE;
}

or, if there is setup that absolutely requires the stage reference, put this in your constructor:

Constructor(){
   if (stage){
      onAddedToStage();
   } else {
      addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
   }
}

private function onAddedToStage(evt:Event=null):void {
   removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
   stage.align = StageAlign.TOP_LEFT;
   stage.scaleMode = StageScaleMode.NO_SCALE;
   initApp();
}
Categories: flex Tags:
  1. August 13th, 2008 at 23:00 | #1

    It’s not a bug in the Flash architecture, it’s a mistake on the part of the developer. AS3 is different than AS1. In AS3, things that have access to stage are not on stage unless you put them there using addChild. This is not a bug, but a developer mistake.

    That being said, most AS3 component authors have proven themselves to be sloppy coders because they release broken components (and charge for them) because they mistakenly assume stage will not be null in the constructor and do not use addEventListener(Event.ADDED_TO_STAGE, onAddedToStage) which is simply good coding practice in AS3. I learned this the very first day I learned AS3, but then again, I read a book about it and didn’t just dive in expecting everything to be the same as AS1.

    The solution is simple:

    if (stage == null)
    {
    addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
    }
    else
    {
    onAddedToStage();
    }
    private function onAddedToStage(event:Event = null):void
    {
    // init code that requires stage
    }

  2. August 14th, 2008 at 07:12 | #2

    Hi Steve,
    Thats why I said I would “kind of” consider it a bug. In the example I’ve included the Loader IS added to the stage before the call to download the SWF. As far as the developer is concerned the SWF has been added correctly beforehand. This is unexpected behavior with how SWFs loaded into SWFs are instantiated.

    Something I’m working on currently involves users being able to specify their own swfs to load. A good portion aren’t working because of this issue. Its just annoying that the authors of those swfs have to have the foresight to take the extra step of making their swf compatible. You can’t expect every swf author to do this or follow this “good coding practice” especially if their swf was never originally intended to be loaded into another swf.

    I’d actually prefer if “stage” was never accessible by a class constructor so that this “best practice” could be a requirement.

  3. sugandha
    August 20th, 2008 at 01:36 | #3

    it helped me…as I was also facing the same problem.
    I still further get few security errors that is surely solvable but besides that I get an error for stage access as well.
    Lets say “swf_contain” is my container swf and “swf_loaded” is my swf being loaded into it.

    Now I get error saying:
    caller “swf_loaded” cannot access Stage owned by “swf_contain”
    at flash.display::Stage/set align()
    at net.slideshare.controller::Controller/onAddedToStage()
    at flash.display::DisplayObjectContainer/addChild()
    at egoWidgetNEW_fla::MainTimeline/playerLoaded()

    I just wanted to understand how flash distinguishes between stage of container and loader swf. because here further loading I want it to access stage of loader swf.

    Any help would be appreciated. Kindly mail me:)

  4. August 20th, 2008 at 06:47 | #4

    Hi Sugandha,
    Your probably loading a swf from a different domain into the first swf. The flash security sandbox prevents cross domain swfs from accessing each others properties unless explicitly allowed through the code. Try adding this to “swf_contain” and it should work:

    Security.allowDomain(“*”);

    Regarding how flash distinguishes between the stage of the container and the loaded swf, they reference the same object.

    All stage properties references the single base-container Stage instance that all SWFs, including your main SWF and nested loaded swfs are contained in. The “stage” property will be “owned” by your main swf so you need to explicitly allow access to it like any other property of the swf using the above.

    There is a nice hierarchy chart here:
    http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00000142.html

  5. sitron
    September 16th, 2008 at 23:57 | #5

    thanks so much!

  6. Suresh
    September 22nd, 2008 at 23:45 | #6

    Hi,
    I have used above code and when I trace the satge its giving as null but from else code the function is not getting triggered on that addEventListener(Event.ADDED_TO_STAGE, onAddedToStage); event…
    donno why? even I cant trace anything in that function..Can any one tell me what Im doing wrong?
    thanks in advance

  7. September 25th, 2008 at 05:51 | #7

    Hi Suresh,
    Perhaps that function isn’t your class constructor. Can you paste the code?

  8. October 6th, 2008 at 23:52 | #8

    You guys are the best. Thanks for the code. bBen searching the net for over 3 hours. Am referring to the topic (swf into swf) in as3. its been bugging sine last night. Your code worked perfectly. Am uploading my new web site in 20 mins. Thanks alot and have a nice day.

  9. Flo
    November 27th, 2008 at 22:52 | #9

    Hi,
    Thanks for the code it helped me a lot, but i try to use this code inside an child swf which have resize and possition function. Everything is working good until i try to resize the swf…I think somethig is wrong with the “possition” function..Bellow i paste my code:

    if (stage){
    onAddedToStage();

    } else {
    addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
    }

    function onAddedToStage(evt:Event=null):void {
    removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
    stage.align = StageAlign.TOP_LEFT;
    stage.scaleMode = StageScaleMode.NO_SCALE;

    possitionBar();
    stage.addEventListener(Event.RESIZE,positionAll);

    }

    function possitionBar():void {
    bar_mc.bar_mc.width = stage.stageWidth-20;
    buttons_mc.x =(stage.stageWidth – buttons_mc.width)/2;

    bar_mc.x = 10;
    buttons_mc.y = stage.stageHeight – ((bar_mc.height-5 )*2);
    bar_mc.y = stage.stageHeight – bar_mc.height;
    //positioning the loader
    _loader_mc.alpha = .2;
    _loader_mc.x = 10;
    _loader_mc.y = bar_mc.y;

    }

    //position all the elements on resize
    function positionAll(e:Event):void {

    try {
    resizeAndPositionTheBigImage(_bigContainer_sp,W ,H,false);

    } catch (e:Error) {
    }
    //positioning the loader
    _loader_mc.x = 10;
    _loader_mc.y = bar_mc.y;

    }

    This is the Url:
    http://www.fashionbehave.com/SV-project/

    Thanks in advance, Flo

  10. Sue Leo
    December 15th, 2008 at 18:26 | #10

    Thanks SO much for this code. I have been looking for an answer for this error in clear understandable terms. I am a designer learning how to code. I had several event listeners on the stage and that was the source of the error code.

  11. January 13th, 2009 at 08:29 | #11

    Hey man, Thanks very much this helped me a lot. i was pulling me hair out (i must have gone through 50 sites before i found your’s with the correct information. def bookmarking the site incase i come up with the problem again and i forget about it).
    Regards
    Mark

  12. David V.
    January 26th, 2009 at 16:04 | #12

    @Steven Sacks
    FWIW- this does not work for me and leads me to believe, like with other problems with the Loader in AS3, it is not a developer problem but a language problem.

  13. Rajneesh
    March 5th, 2009 at 01:16 | #13

    Hi,

    I am designing a simple app of loading swfs.
    Idea is there is file name home.swf having 6 buttons. Each button will load a releated swf and the home.swf will be gone completely from the stage. Now in loaded swf there is button for home.swf to come back to home. this was working fine. But when i added document class which loads xml data into list component, the button on home.swf for this swf, shows error as,

    TypeError: Error #1009: Cannot access a property or method of a null object reference.
    at loadXMLDoc$iinit()

    loadXMLDoc.as is in same folder.

    please help me.

  14. Matt
    March 19th, 2009 at 14:02 | #14

    This was very, very helpful. Thank you!

  15. March 29th, 2009 at 18:29 | #15

    Thanks, this helped out a ton.

  16. Kridian
    April 28th, 2009 at 12:48 | #16

    I would like to know the answer to Rajneesh’s question as well. Having a Flash site that swaps out swfs (pages). In my case the object is a scrollbox movie clip in one of the swf pages causing that error. [?]

  17. July 13th, 2009 at 14:41 | #17

    Thank you so much. I would have never thought to look for this, but it makes complete sense. The generic error would have had me searching for hours/day if I hadn’t read this. Thanks!

  18. zoeerp
    August 24th, 2009 at 12:06 | #18

    Thanks! Very helpful! :)

  19. Alejandro
    February 23rd, 2010 at 09:20 | #19

    @markledford
    If I’m working on the Flash IDE and i wanted to include this code on the first frame of the swf that’s going to be loaded, how will the code look like?

  20. anothervictimofNOstage
    March 1st, 2010 at 18:51 | #20

    WOW!, thank you soooooooooooooo much…

  21. Nick
    March 26th, 2010 at 04:37 | #21

    Thank you for the clear help. My projects are normally small or modular, so i hadn’t had to preload a large main file before (in AS3). Big Hugs xxx

  22. mazari
    May 20th, 2010 at 04:35 | #22

    thank you so much , this was really helpfull to me

  23. anonymous
    July 25th, 2010 at 13:32 | #23

    Another similar error is when an SWF relies on this.loaderInfo to be present — this would work if the current object is the root of display hierarchy, but will not if it is a child of another SWF.

  24. Khoa
    September 22nd, 2010 at 19:39 | #24

    I’ve encounter this null stage reference error and know the solution as well.
    BUT I still wonder why the erroneous flash run well as standalone. How can the local reference to stage is assigned before its constructor?!

  25. Andreas
    October 6th, 2010 at 14:49 | #25

    Yooooooooo!

    Thank you so much, been exploding cause of this and now it works …Thank you

  26. opacts
    May 4th, 2011 at 02:38 | #26

    many many thanks saved a lots of hairs of my head :)

  27. June 18th, 2011 at 13:57 | #27

    This code works only when you generate swf. In loaded swf doesn’t.

  28. May 3rd, 2012 at 14:18 | #28

    Thank you very much, very helpful.

  29. Greg
    September 25th, 2013 at 03:28 | #29

    I stumbled onto your blog Mark, nice.

  1. August 13th, 2008 at 22:24 | #1
  2. November 9th, 2008 at 20:18 | #2
  3. February 15th, 2009 at 07:34 | #3
  4. March 2nd, 2009 at 21:44 | #4
  5. March 30th, 2009 at 07:50 | #5
  6. April 6th, 2009 at 07:17 | #6
  7. October 18th, 2011 at 11:19 | #7