Aug 03 2004

Flex Tip 2: MXML Script-tag content is not HTML JavaScript

Published by at 23:46 under Wayback Archive

I’ve seen developers with an HTML/JavaScript background that move into MXML make a very common mistake: they all call a function inside a script block but outside a function definition. This causes the Flex compiler to throw an error. This post explains what is causing this and helps you to avoid this in the future.

First let’s explain you what these developers are trying to achieve. They want some variables to be assigned a value that is returned by a function when the application starts. Or, at start of the application they want a function to be triggered immediately to do some specific actions.

If you want to do this in JavaScript in your HTML document you can use the following script:

<script>
function returnSomething() {
    return “something”;
}
var myVar = returnSomething();
</script>

However, if you do this in the MXML equivalent <mx:Script> you will get an error: “A class’s instance variables may only be initialized to compile-time constant expressions.”

Something else that JavaScript developers do a lot is this:

<script>
function doSomething() {
    // do something
}
doSomething();
</script>

If this is done in your <mx:Script> tag you get the following error: “This statement is not permitted in a class definition.”

So now the question is, why does this not work in Flex? The answer is very simple once you understand what actually happens under the hood. The compiler warning should already be an indication, but in case you did not know; all the MXML tags that you have defined in your document are turned into one single ActionScript Application class by the Flex compiler (you can see this by setting ‘keep-generated-as’ to true in flex-config.xml and studying the generated ActionScript class).

For all the scripts in your <mx:Script> tag it means that their content is simply ported into the class as well. So the functions you defined become methods of the class, the variables you defined become properties of the class.

Therefore, all the code you write into the <mx:Script> tags should adhere to the rules that are defined for ActionScript 2.0 classes. One of them is that “your class’s instance variables may only be initialized to compile-time constant expressions”, and calling functions is only allowed inside other functions. (Colin Moock described this in detail in his Essential ActionScript 2.0 book).

So how can you trigger a function at startup of your application? Simple use the ‘initialize‘ or ‘creationComplete‘ events of your <mx:Application> tag like this: initialize=”doSomething();” or creationComplete=”doSomething();”.

BTW: I’ll give more info on initialization and creationComplete in the next post.

8 responses so far

8 Responses to “Flex Tip 2: MXML Script-tag content is not HTML JavaScript”

  1. Sven Claar says:

    Thanks for this explanation at the right time!
    This question is one of my favourites 😉

    Cheers,
    Sven

  2. Waldo Smeets says:

    Hi Sven, glad to hear you find it usefull :o)

  3. Marco Casario says:

    Hi Waldo,
    i think that another big mistake that flash developers are trying to achieve is to not think Flex event based model and the different usage of methods defined inside their AS classes..
    Read the flex docs is a must for every flash or javascript developer …
    thanks,

  4. Sander Prins says:

    Nice to see that this is a common mistake to make, thanx for helping me out earlier on this one 😉 The solution is very simple, but until you see what’s going on, these are the sort of things that really get your blood boiling…

  5. Waldo Smeets says:

    No need to worry Sander, you were not the only one that gave me the idea to blog about this. I think we all once have made this mistake and yes, so did I 🙂

  6. Waldo Smeets says:

    Hi Sven, glad to hear you find it usefull :o)

  7. Tushar says:

    Hi Waldo,

    I am getting the same error, ‘…not permitted in class definition’, when I use following function definition:

    Lexer.prototype.Next = function() {
    //do something
    }

    Thanks to your post, now I know that it is due to Flex compier making a single application class. However I do not know what can be the problem behind above function. Please help.

    Tushar

  8. Waldo Smeets says:

    Hi Tushar, I have not looked into it yet but I guess it’s the ‘prototype’ thing. In ActionScript 2.0 (and Flex is ActionScript 2.0) methods are not added using the prototype chain, you can now just create a clean Lexer class and define the method in your class file as a function.

    Lexer.as:
    class Lexer {
    function Lexer(){
    }

    function Next(){
    }
    }