Skip to main content
October 17, 2010
Answered

Problem passing a string as a movie clip instance name

  • October 17, 2010
  • 3 replies
  • 619 views

Hey there folks,

I thought this would be a simple one, but i am stumped.  So I resulted to using this less than optimal solution, just to get it working...

     if (lobby.gamemap.selectedItem.label == "Map1") map.AddMap(new Map1)

     else if (lobby.gamemap.selectedItem.label == "Map2") map.AddMap(new Map2)

     //Map1 and Map2 are movie clips in my fla library, with linkage Map1 and Map2

I have a lobby class, inside this is a combo box with the map choices...the problems arise when I try this prefered implementation

     map.AddMap( lobby.gamemap.selectedItem.label )

     //Throws Error - Type 1067: Implicit coercion of a value of type String to an unrelated type flash.display:MovieClip

i read in this post http://forums.adobe.com/message/2741961 that flash should be able to use this[string] to pass the string as movie clip instance name...so i tried

     map.AddMap( this[lobby.gamemap.selectedItem.label] )

     trace(this[lobby.gamemap.selectItem.label])

     //This also throws an error, TypeError: Error #2007: Parameter child must be non-null.

     //I also note that the trace comes back null...

I tried this, inclusion of the word 'new'

      map.AddMap(new this[lobby.gamemap.selectedItem.label] )

     //This throws - TypeError: Error #1007: Instantiation attempted on a non-constructor.

I also tried passing lobby.gamemap.selectedItem.label to a string, and trying all the previous situations with the string instead of the comboBox label.

..still no dice.

Haaalp

This topic has been closed for replies.
Correct answer Ned Murphy

Your preferred approach won't work for what is hopefully obvious.  Whatever the AddMap function is doing, it is expecting a MovieClip as an argument, not a String.  Using the bracket notation as you tried in the next attempt fails because the instance has to exist to target it that way.  And the last is just wrong, partly for the previous reason and partly because an instance cannot be used directly as a class identifier.

Here is some code that can be used to create a new instance using a String value for the class name.  See if you can adapt this...

var ClassRef:Class = Class(getDefinitionByName("className"));
var classInstance:* = new ClassRef();

3 replies

October 19, 2010

@ Andrei

Thanks for the broad considerations, this led me to inspect my code a little harder.  I'm working with a serverside api, and I wasn't utilizing some handy server data functions to store my map string.

@Ned

Aha!  I was very confused about how to pass a string as a MovieClip.  I was unaware you have to use the string to create a class instance, and use the class instance to add the MovieClip from the library...

I based my original assumptions on this...

addMap(new Map1)

being the same as

var temp:string = "Map1"

addMap(new temp)

...and assumed it would work, a Map1 is a Map1 right? Wrong...

Thanks to you both for the clarifications!

Inspiring
October 17, 2010

Ned's comments are right on the money and his suggestion to use class definition is probably the only way to get a class based on string value. Nevertheless, this kind of dynamism is good only when there is a need for high level abstraction, particularly when external runtime downloaded libraries are used (classes are not available at compilation).

I think your solution with conditionals is more sensible and controllable because you know your library content, so why not to utilize this knowledge directly? It is faster too from performance standpoint.

Also, conceptually, dynamic based on string instantiation is dangerous because good compiler will not make library classes available unless there are instances declarations throughout the application.

Ned Murphy
Ned MurphyCorrect answer
Legend
October 17, 2010

Your preferred approach won't work for what is hopefully obvious.  Whatever the AddMap function is doing, it is expecting a MovieClip as an argument, not a String.  Using the bracket notation as you tried in the next attempt fails because the instance has to exist to target it that way.  And the last is just wrong, partly for the previous reason and partly because an instance cannot be used directly as a class identifier.

Here is some code that can be used to create a new instance using a String value for the class name.  See if you can adapt this...

var ClassRef:Class = Class(getDefinitionByName("className"));
var classInstance:* = new ClassRef();

October 17, 2010

ahoy sir!

thank you for the quick reply, concise explanation and code example.

i see now where i went wrong, trying to pass a movie clip instance instead of a class instance.  here's my working code.

var ClassRef:Class = Class(getDefinitionByName(lobby.gamemap.selectedItem.label));
var classInstance:* = new ClassRef();

map.AddMap(classInstance)


//after a second glance, i've abreviated the code to only two lines

var ClassRef:Class = Class(getDefinitionByName(lobby.gamemap.selectedItem.label));

map.AddMap( new ClassRef())

Ned Murphy
Legend
October 17, 2010

You're welcome.  Just so it's clear, a class instance is a MovieClip (in your/this case).  Reread my descriptions as to why what you had didn't work--in none of those were you trying to pass a legitimate MovieClip.