AS3 - The supplied DisplayObject must be a child of the caller error while removing swf - actionscript-3

please help i am getting this error and could not solve with any of the other methods described in all previous posts with similar topic.
Actually here i am loading a swf myMap onto another swf.
The swf loading works fine, but when try to remove this from stage i get the above said error...
ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
at flash.display::DisplayObjectContainer/removeChild()
at actions.classes::MapInteractionManager/unloadSWF()
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
Here's my as3 code...
var _swfLoader:Loader;
var _swfContent:MovieClip;
loadSWF("myMap.swf"); //loading the swf file here
function loadSWF(path:String):void {
var _req:URLRequest = new URLRequest();
_req.url = path;
_swfLoader = new Loader();
setupListeners(_swfLoader.contentLoaderInfo);
_swfLoader.load(_req);
}
function setupListeners(dispatcher:IEventDispatcher):void {
dispatcher.addEventListener(Event.COMPLETE, addSWF);
dispatcher.addEventListener(ProgressEvent.PROGRESS, preloadSWF);
}
function preloadSWF(event:ProgressEvent):void {
var _perc:int = (event.bytesLoaded / event.bytesTotal) * 100;
// swfPreloader.percentTF.text = _perc + "%";
}
function addSWF(event:Event):void {
event.target.removeEventListener(Event.COMPLETE, addSWF);
event.target.removeEventListener(ProgressEvent.PROGRESS, preloadSWF);
_swfContent = event.target.content;
_swfContent.addEventListener("close", unloadSWF);
main.stage.addChild(_swfContent);
}
function unloadSWF(event:Event):void {
_swfLoader.unloadAndStop();
main.stage.removeChild(_swfContent); //getting error when trying to remove swf
_swfContent = null;
}
and close event is as,
_swfContent.dispatchEvent(new Event("close"));
Please help, I'm stuck.
here with some update,
i updated code as,
function unloadSWF(event:Event):void
{
if(main.stage.contains(_swfContent))
main.stage.removeChild(_swfContent);
}
Now the error is gone as it is not entering the if loop!!!???
But still i can see that swf on stage:( plz help
GOT SOLVED...
Thanks everyone for helping...
ToddBFisher did solve it:)
Simply added the _swfLoader to the stage, loaded it, and attached the close listener to it instead of even having a _swfContent. Cut out the middle man and it worked.... Hope this helps...

As I recall .unloadAndStop(); does a bunch of cleanup type things, which you are calling right before. It is possible part of the cleanup is removing it from the display list.
Try calling the removeChild() before calling unlodaAndStop()
function unloadSWF(event:Event):void {
stage.removeChild(_swfContent); //getting error when trying to remove swf
_swfLoader.unloadAndStop();
_swfContent = null;
}
EDIT
Try simply adding the _swfLoader to the stage, load it, and attach the close listener to it instead of even having a _swfContent. Cut out the middle man and see what happens.

The error means the child is already removed (or never added)
try to comment out
_swfLoader.unloadAndStop();
to see if it works.

main.stage.removeChild is already setting _swfContent to null because removeChild was fired so removing the line _swfContent = null might solve it.

Related

How to fix 'TypeError: Error #1009' error in ActionScript3.0 Adobe Animate

I'm setting up a button on the first frame which when clicked will transfer the user to the 2nd frame using this code:
stop();
Btn_1.addEventListener(MouseEvent.CLICK, fl_ClickToGoToAndPlayFromFrame_2);
function fl_ClickToGoToAndPlayFromFrame_2(event:MouseEvent):void
{
gotoAndPlay(2);
}
and on the second frame, I set up a dynamic text that will perform a countdown using this code:
var myTimer:Timer = new Timer(1000,60); // every second for 60 seconds
myTimer.addEventListener(TimerEvent.TIMER, onTimer);
myTimer.addEventListener(TimerEvent.TIMER_COMPLETE, onComplete);
myTimer.start();
function onTimer(e: TimerEvent):void {
countdown_text.text = String(myTimer.repeatCount - myTimer.currentCount);
}
function onComplete(e: TimerEvent):void{
gotoAndStop(3);
}
the thing is keep getting TypeError: Error #1009 message after debugging it. I know the fault is in line 7 of the 2nd code but I have no idea what is wrong with it. Pls help!
I should see your source fla, but it is most likely related to countdown_text not being accessible in that frame. Error description is "Cannot access a property or method of a null object reference", that means it cannot find the reference which is "countdown_text".
It is very very bad practice to write AS directly in frames. Convert code into a class and assign it as a document class.
You can find Adobe documentation for document class here: https://helpx.adobe.com/animate/using/actionscript-publish-settings.html

removechild not working when the swf is loaded externally

my problem is that the close button (removechild) which is placed in a swf works perfectly alone but when the swf is loaded from another one the button no longer works.
Here's the external swf code:
eti_scroll.scrollTarget = box_eti ;
hab_scroll.scrollTarget = box_hab ;
com_scroll.scrollTarget = box_com ;
descr_scroll.scrollTarget = box_descr ;
exit.addEventListener(MouseEvent.CLICK, exitBtn_clickHandler);
function exitBtn_clickHandler(event:MouseEvent):void {
if(this.parent) this.parent.removeChild(this);
}
And here's the button code from the main swf:
menu_button_2.addEventListener(MouseEvent.CLICK, fl_MouseClickHandler2);
function fl_MouseClickHandler2(event:MouseEvent):void
{
var myLoader:Loader = new Loader();
var url:URLRequest = new URLRequest("pages/page_template.swf");
myLoader.load(url);
addChild(myLoader);
}
In the main swf there is no packages imported or loaderclass
Here is the link to the fla version and the example version:
http://www.mediafire.com/file/5dzqnq3kth6n6dt/examples.rar
Error thrown when I use trace code by #organis and loaded from an external SWF file:
The error thrown:
I am here! Exit Button: [object SimpleButton] object Event Handler: function
Function() {} function Exit.addEventListener: function Function() {} function
MouseEvent.CLICK This: [object MainTimeline] object Parent: [object Loader]
object Parent.removeChild: function Function() {} function Error: Error #2069:
La clase Loader no implementa este método(The Loader Class doesn't implement
this method). at Error$/throwError() at flash.display::Loader/removeChild() at
page_template_fla::MainTimeline/onClick()[page_template_fla.‌​MainTimeline::frame1‌​
:65] –
Let me explain how to deal with this kind of problem. Once something that is supposed to work does not, the first thing to do is to pinpoint where the problem starts exactly, so you can probably diagnose what the problem is rather than have a vague understanding there is a problem somewhere.
So you read all the traces from standalone run, then from loaded run and there certainly must be a difference. Upon finding it, you act with the regard to what that difference is.
// If this does not work, that means scripts do not work in the loaded SWF at all.
trace("I am here!");
// If this doesn't work the same as standalone, that means
// something breaks while constructing the loaded content.
trace("Exit Button:", exit, typeof(exit));
// Lets check id the event handler is doing fine.
trace("Event Handler:", onClick, typeof(onClick));
// If the method is not present on the object,
// something is deeply wrong with the whole thing.
trace("Exit.addEventListener:", exit.addEventListener, typeof(exit.addEventListener));
exit.addEventListener(MouseEvent.CLICK, onClick);
function onClick(event:MouseEvent):void
{
// If it doesn't work that means there's no mouse event.
trace("MouseEvent.CLICK");
// Just to check things out.
trace("This:", this, typeof(this));
trace("Parent:", this.parent, typeof(this.parent));
trace("Parent.removeChild:", this.parent.removeChild, typeof(this.parent.removeChild));
if(this.parent) this.parent.removeChild(this);
}
UPD: Now, you're getting the error (you should have mentioned it in your question in the first place, actually)
Error: Error #2069: La clase Loader no implementa este método(_The Loader Class doesn't implement tihs method_). at Error$/throwError() at flash.display::Loader/removeChild() at page_template_fla::MainTimeline/onClick()[page_template_fla.‌​MainTimeline::frame1‌​:65]
Now take a look here (I like this link as it explains quite a lot): https://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7e26.html
Your script is on the main timeline. So, when you run it in a standalone mode, this.parent points to stage which can add and remove children, no problem.
Then, when you run it in the loaded mode, the hierarchy goes main SWF stage -> main SWF root -> ... -> Loader -> loaded SWF root. As you can see, when you address this.parent you get the Loader instance, the very one you use in main SWF to load the other one. Loader is a DisplayObjectContainer but is not intended for adding/removing children, thus it throws the exception mentioned above.
With all this I advise another way of removing content out of sight:
exit.addEventListener(MouseEvent.CLICK, onClick);
function onClick(event:MouseEvent):void
{
// Unsubscribe to help Garbage Collector do its job.
exit.removeEventListener(MouseEvent.CLICK, onClick);
// Hide the content.
visible = false;
// Remove all of its children.
removeChildren();
}
Or you can figure the case your script is running in and act accordingly:
exit.addEventListener(MouseEvent.CLICK, onClick);
function onClick(event:MouseEvent):void
{
// Unsubscribe to help Garbage Collector do its job.
exit.removeEventListener(MouseEvent.CLICK, onClick);
// Checking for
// if (parent == null)
// is unnecessary here because if that was the case
// there won't be a mouse event in the first place.
var aParent:DisplayObjectContainer = parent;
if (aParent is Loader)
{
// Loaded case.
aParent.parent.removeChild(aParent);
}
else
{
// Standalone case.
parent.removeChild(this);
}
}
However, that figuring will only work in the simple cases and will not in more complicated setups (cross-domain content, security sandboxes, etc).

AS3 null-object reference

So heres the code:
function playSound():void
{
var channel:SoundChannel = sound.play();
channel.addEventListener(Event.SOUND_COMPLETE, onComplete);
}
function onComplete(event:Event):void
{
SoundChannel(event.target).removeEventListener(event.type, onComplete);
playSound();
}
I get the error on channel.addEventListener(Event.SOUND_COMPLETE, onComplete);
but I dont get it at the start, as a game runs for some time without the error, so Im suggesting theres a problem in a onComplete function or an event listener, however, all I tried had failed and Im stuck here for some time now.
I just decided to post it here and see if anybody can see the problem.
Thanks in advance!
EDIT:
Sorry I havent included this right away.
Error:
TypeError: Error #1009: Cannot access a property or method of a null
object reference. at
projectSnowFlake_fla::MainTimeline/playSound()[projectSnowFlake_fla.MainTimeline::frame1:275]
at
projectSnowFlake_fla::MainTimeline/playGame()[projectSnowFlake_fla.MainTimeline::frame1:269]
at
projectSnowFlake_fla::MainTimeline/gameLoop()[projectSnowFlake_fla.MainTimeline::frame1:156]
[UnloadSWF] projectSnowFlake.swf Test Movie terminated.
And heres the sound :
var sound:Sound = new MainSound();
I read your code, the only potentially issue is sound variable, can be null.
Have you instantiated sound variable?
If sound is valued, the method play (of variable sound) can return a null value?
EDIT AFTER COMMENTS:
Hi, view this and this issue

Removing an event listener as well as a sprite at the same time AS3

I’m having trouble removing the an event listener as well as the sprite at the same time. I currently get an error:
TypeError: Error #1009: Cannot access
a property or method of a null object
reference.
And if I comment out removeChild, I have no error but, obviously, the sprite remains on the screen. Any ideas how I can rid myself of that error?
//Bullet extends Sprite Class
bullet:Bullet = new Bullet();
mc.addChild(bullet);
bullet.addEventListener(Event.ENTER_FRAME, shoot);
function shoot(e:Event):void {
var shot:Bullet = e.currentTarget as Bullet;
//check shot is outside the frame
if (shot.x < 0 - shot.width || shot.x > stage.stageWidth || shot.y > 525)
{
//trying to remove the thing and it's listener
e.currentTarget.removeEventListener(e.type,arguments.callee);
e.currentTarget.parent.removeChild(shot);
}
else
{
shot.setInMotion();
}
}
Apart from a missing var before bullet:Bullet, I don't see anything wrong in the example code. You should set a breakpoint right after:
var shot:Bullet = e.currentTarget as Bullet;
And figure out why shot is null. I suspect there is something amiss in a piece of code outside of the little bit you're providing as the example. If the code is working with only the removeChild line commented out, it tells me that e.currentTarget is not null, but that it's also not a reference to an instance of type Bullet (i.e. the "as" cast is returning null).
Try reversing these lines
Maybe the reference to e.currentTarget is getting lost through the object references
e.currentTarget.removeEventListener(e.type,arguments.callee);
e.currentTarget.parent.removeChild(shot);
to
e.currentTarget.parent.removeChild(shot);
e.currentTarget.removeEventListener(e.type,arguments.callee);

External SWF Loading problem

I have an SWF loading in an SWF containing a papervision scene.
I've done it before yet problem is, I get an error - I'm not sure what the issue really is.
private function downloadSWF(url:String):void
{
trace(url);
var urlRequest:URLRequest = new URLRequest(url);
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, loaderProgressEventHandler);
loader.load(urlRequest);
}
private function loaderProgressEventHandler(ev:ProgressEvent):void
{
loader.preloaderCircle.percent = ev.bytesLoaded / ev.bytesTotal;
}
When the application runs the code - I get the error:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at com.dehash.pv3d.examples.physics::WowDemo()
Why am I getting this if the loading hasn't even complete yet?
Thanks in advance guys.
Edit: Try a blank child swf, see if the other one was trying access something in the parent. – Jorge
I did this, it seems, even with a simple SWF with a mouse click listener causes the Error:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at simple_fla::MainTimeline/frame1()
My code for that is:
import flash.events.MouseEvent;
this.stage.addEventListener(MouseEvent.CLICK, onClick);
function onClick(ev:MouseEvent):void
{
trace("MouseClick");
}
Am I missing something blatantly obvious??
The problem is that the loaded swf starts running without it being added to the stage. So stage is null, resulting in that error.
The second example with the addedToStageEventHandler works because there stage is only referenced after the object was added to the stage, so stage is not null anymore.
A possible solution for the first error is adding the loader to the stage. That way, when the swf is loaded and starts, it already has a stage reference.
It won't even load if there's an error. You're accessing an unreferenced object on the WowDemo() class...did you instantiate correctly the class?
this seems to work inside my child SWF:
this.addEventListener(Event.ADDED_TO_STAGE, addedToStageEventHandler);
function onClick(ev:MouseEvent):void
{
trace("MouseClick");
var event:Event = new Event("END", true, false);
this.dispatchEvent(event);
}
function addedToStageEventHandler(ev:Event):void
{
this.stage.addEventListener(MouseEvent.CLICK, onClick);
}
does anyone know Why?