views:

29

answers:

3

Hi:

I've a simple application with one movie loading another SWF in the same domain. I can access vars and functions in the loaded SWF but can't listen events from a button; receiving the run-time error: Error #1009: Cannot access a property or method of a null object reference

The Linkage properties for the button are set

Main

var assetLoader:Loader = new Loader();
assetLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,loadingComplete);
assetLoader.load(new URLRequest("home.swf");

function loadingComplete(evt:Event):void {
...
var asset:MovieClip = assetLoader.content as MovieClip;
asset.homeTrace("function in loaded SWF");
trace("var in loaded SWF:", asset.lastFrame);
// Error #1009
asset.enterApp.addEventListener(MouseEvent.CLICK, homeButtons);
...
}

Home

var lastFrame:Boolean = false;

function homeTrace(p1:String) {
  trace(p1);
}

Thanks in advance

A: 

I've implemented a solution, not what I wanted but is working fine. As i'm not able to add listeners for buttons in loaded movie, I added a general one and used a switch to discriminate the sender object:

asset.addEventListener(MouseEvent.CLICK, homeButtons);
...
function homeButtons(evt:MouseEvent):void {
  switch(evt.target.toString()) {
    case "[object Send]":
      nextScreen(evt);
      break;
    case "[object Enter]":
      tmpEnter(evt);
      break;
  }
}
hsands
A: 

You post a regular solution, but if you'll look deeper you could find solution how to add event listeners here and read about whole architecture here.

Regards
Eugene

Eugene
@Eugene: I'll take a closer look at the Adobe forum posts. Regarding the article in gskinner's blog, it's a Flex based solution and I'm using Flash IDE. And yes, you're right, looking deeper you can even found oil or gold! The problem is knowing where to look! ;-)
hsands
A: 

The problem could be that you are casting the 'asset' as a MovieClip, it could well be a Sprite. Best to put the whole thing in a try .. catch or if just in case anyway, and cast it to the safe * type to avoid compile time errors (or if you wanted to go the whole home use an interface and merge the two applicationDomain contexts, but thats an expansive topic)

function loadingComplete(evt:Event):void {
   ...
   var asset:* = assetLoader.content;
   if(asset != null){
      try{
         connectModule(asset);
      }catch(err:Error){
         trace("Error accessing module functions", err.getStackTrace());
      }
   }else{
      trace("No module");
   }
}

function connectModule(module:*):void{
   trace("Using typeof", typeof(module), "using constructor", module.constructor, "has the function?", module['homeTrace'] != null);
   module.homeTrace("Function load in swf");
   ...
}

The trace statements in connectModule should give you some extra debugging information to help you determine what type of object is loaded and whether or not it has the function you are attempting to access. Let me know if this works for you.

@user61466: sorry for the delay and thanks for your time! I'll give a try to your suggestion just for the sake of curiosity but the SWF's I'm loading are plain Flash movies with some timeline animations, a couple of SimpleButtons and a stop() in the last frame. So, I can't see how they could be something different than a MovieClip instance
hsands
@hsands: Ah sorry, this is not important then. Just looking over the sample again, error: 1009 is null object reference i.e. The thing you are accessing is not there, I notice this is just before `asset.enterApp` this means that whatever `enterApp` is, it is not there. If this is a movieclip on the stage then there are a couple of rendering delays with the Flash player that would cause these not to be on the stage straight away. Best to wait a frame with `addEventListener` (or setTimeout if you need something hacky) until `enterApp` is rendered.