A very common ActionScript error is Error 1120, the "undefined property" error. In fact, this may be the most common compile-time error. Its cause is very simple, but there are a number of ways it can actually be induced. We'll take a quick tour of some of the scenarios in which you'll encounter this error, and how to fix them.
The Explanation
First, let's get the general idea of what's going on with this error. This will be our theoretical discussion; we'll get to more practical examples in the remainder of the tip.
You find this error occurring when you reference a variable (or property) in a line of code, but that variable doesn't exist. If you're used to writing ActionScript in the Script panel, and not in classes, then don't be put off by the term "property." I won't get into a lengthy discussion on why we have these two terms, but suffice it to say that given the way ActionScript compiles code from the Script panel, a variable is actually a property.
If the ActionScript compiler can't find the property you've specified, it flags it with compiler error 1120. You'll see something like this:
1120: Access of undefined property foo.
Where "foo
" is the name of your offending property name.
Solving this usually as easy as getting the name right. Let's take a look.
Example 1: No Variable Declaration
Take this code for example (if you like, you can either open up the "missing" example project (that is, the project named "missing" in the source download) or create this project on your own: just create a new Flash file and a document class for it, and put this code in the document class):
package { import flash.display.*; public class Missing extends Sprite { public function Missing() { foo = "Moo."; } } }
Compile this FLA, and you'll get the 1120: Access of undefined property foo.
error, directed at line 7.
Again, the cause is probably very clear; you've never declared the foo
property and so using it in line 7 as if it already existed causes problems. The solution is to simply declare the variable. Technically, this can exist anywhere in the appropriate scope. Each of the following are acceptable solutions:
Declare it as a parameter to the method:
public function Missing(foo:String) { foo = "Moo."; }
Declare it as a local variable inside the method:
public function Missing() { var foo:String; foo = "Moo."; }
Declare it as an instance property in the class:
package { import flash.display.*; public class Missing extends Sprite { private var foo:String; public function Missing() { foo = "Moo."; } } }
The solution depends on what's appropriate to what you're trying to do. It's not common to declare a method parameter and then simply set it in the method body, although there are cases where you want to affect the parameter values.
What may be interesting is the way in which Flash will search for a variable of the name. First, it looks for a local variable of the name foo
. If one was not declared, then it looks at the parameters for that name. If it can't find one there, it looks for an instance property of the same name. If none of these are found, you'll see error 1120.
Example 2: A Typo
Our next example will be rather similar. Again, you can simply open up the "typo" project from the download; or create a simple FLA with document class and paste/type the following code into the class; or just read along.
package { import flash.display.*; public class Typo extends Sprite { var foo:String; public function Typo() { boo = "Moo."; } } }
There isn't much going on here. The idea is to declare a property called foo
, and then in the constructor set that to the value "Moo."
. The meat of this is on lines 5 and 9, highlighted above. The rest is just document class boilerplate.
Again, the error is probably painfully obvious. And of course it is, when there are only two lines of code to concern yourself with. Clearly we have a typo; we meant to write:
foo = "Moo.";
And if you fix the typo, you'll be able to compile the FLA without the 1120 error.
While this one is obvious, I want to make two notes. The first is that typos like this are actually somewhat common and harder to deduce when you have thousands of lines of code in your project. A good IDE or text editor can help you by providing autocompletion or other kinds of error checking, but as a failsafe ActionScript will also help you out by producing the Error 1120.
The second note is that the error that ActionScript is actually reporting is that you are attempting to reference a property called "boo
", but it is not finding one. In this example, we have produced the error by introducing a typo into our code. But ActionScript doesn't know that you really meant "foo
"; it assumes that when you write "boo = "Moo.";
" that you meant boo
, and warns you when it can't find a property of that name.
This is a rather subtle distinction, but it's helpful to keep in mind the true cause of the error.
Example 3: Declaring Stage Instances
Our final example involves the Flash IDE in particular, and can be safely ignored if you're not using Flash CS3/4/5, and instead using Flash Builder with the Flex Framework. Setting up the error will take a few simple steps.
You can find the problematic project in the stage-instance folder of the download package. Or you can re-create it by following these steps:
- Start with a new Flash file and associated document class.
- In the Flash file, draw a shape of some kind and turn it into a symbol.
- Select the symbol instance on the stage and open the Properties panel, and name the instance
instance_mc
. - Still in Flash, choose File > Publish Settings then select the Flash tab.
- Click on the Settings… button next to the "Script:" pop-up menu.
- Where is says Stage: Automatically declare stage instances, make sure the checkbox is unselected.
-
Add the following code to the document class:
package { import flash.display.*; public class StageInstance extends Sprite { public function StageInstance() { instance_mc.rotation = 45; } } }
At this point, go ahead and run the movie. You'll once again get the 1120 error.
As you might be able to surmise, turning off "Automatically declare stage instances" had a lot to do with the generation of the error. It is an option that is by default turned on, so you'd probably have a reason for — and be aware of — turning it off.
What is does if fairly self-explanatory, but I'll add my two cents. When you have a document class (or a custom class linked to a symbol in the library), that class extends Sprite
or MovieClip
. The typical rules for creating variables and properties apply just like any other class, but because you have a visual interface to this object — the Flash IDE — you may be implicitly adding properties by way of drawing more symbols on the stage and giving them instance names.
If "Automatically declare stage instances" is on, then Flash will go through the objects added to the stage through the IDE and insert property declarations to the appropriate classes for each symbol instance with a name.
If it's off, then Flash will do nothing with the instances on the stage.
To avoid the error, you can simply turn this option back on. Alternatively, you can manually declare the stage instances. If we made our document class look like this:
package { import flash.display.*; public class StageInstance extends Sprite { public var instance_mc:MovieClip; public function StageInstance() { instance_mc.rotation = 45; } } }
This would also avoid the error, because the property is still declared; it just hasn't been declared automatically by Flash Professional.
Note that if the access modifier is not public
you will get a runtime error. I'm not going to go into detail on this error; that will be for another Quick Tip.
Now, why would you ever want to turn that option off in the first place? I think the reasons all have to do with moving beyond Flash as a development tool. If you use Flash Builder to code, or ASDoc, or integrate Flash content within a Flex project, you might appreciate the ramifications of turning the option off. If you turn it off, you are forced to then declare the properties manually. The opposite is also true: if you turn it on, you are forced to not manually declare those properties.
Thus, if you run your class files through ASDoc, it will most likely find a reference to a stage instance, but not its declaration, and you'll receive error 1120. Turning the option on is a convenience, but turning it off forces you to write more "pure" code that is more portable and self-contained.
I Declare This Quick Tip Done
Like many errors, Error 1120 is simple at heart, and easy to fix once you know what to look for. Thanks for reading, and stay tuned for more debugging Quick Tips!
Comments