How to Retrieve FlashVars Data in ActionScript 3.0

Flash ActionScript 3.0

Last year around this time, I described how to pass variables into a SWF by way of something called FlashVars.  This was discussed in “How to Tell a SWF What File(s) to Load — From the Outside” which works for pretty much any sort of simple data you may want to pass in, as long as you’re talking about relatively small groups of name/value pairs.  Complex data is more likely to be suited to XML.  In that earlier blog entry, the purpose was to re-use a single SWF numerous times to load a variety of MP3 files, by specifying which audio in the HTML.  Pretty flexible solution!  You could use the same technique for loading JPGs or FLVs, to populate dynamic text fields, or whatever you like.  The article has been fairly popular and continues to be useful — as long as your SWF is published for ActionScript 2.0 (or even 1.0 if you drop the post colon suffixes — :String, :Number, and the like).  In ActionScript 3.0, things are different. 

The updated code

There are two halves to getting this sort variable into Flash:  the HTML side and the ActionScript side.  Fortunately, the HTML side hasn’t changed at all.  Even with an ActionScript 3.0 SWF, you can read the existing “From the Outside” article and continue to follow the instructions as stated, even for the SWFObject (JavaScript embedded SWF) section at the end.  The difference comes within the first few paragraphs on ActionScript 2.0.  And even so, the code as shown in that article …

But clearly, this approach is hard coded.  In order to open up the possibilities, replace the path reference with a variable — let’s just call it audio.

var s:Sound = new Sound();
iconButton.onRelease = function():Void {
 s.loadAudio(audio, true);
}

… comes fairly close to the updated syntax.

In ActionScript 3.0, incoming FlashVars variables are no longer available as a loose collection in the main timeline.  In the above AS2 code, the audio variable is passed in to the SWF from the HTML document and is therefore not declared in the movie.  In AS3, such variables have been moved to the parameters property of a LoaderInfo instance associated with the main timeline.  The LoaderInfo class “provides information about a loaded SWF file or a loaded image file (JPEG, GIF, or PNG).  LoaderInfo objects are available for any display object [this means instances of the DisplayObject class, which includes movie clips].  The information provided includes load progress, the URLs of the loader and loaded content, the number of bytes total for the media, and the nominal height and width of the media.” source

To get to the LoaderInfo instance associated with the main timeline, you may refer to the DisplayObject.loaderInfo property of the main timeline.  Remember, the main timeline is a descendent of the DisplayObject class; it can be treated as a movie clip (an instance of the MovieClip class) or a sprite (an instance of the new Sprite class) — but we don’t need to worry about that here.  The punch line is simply that instances of DisplayObject have a loaderInfo property that points to their own private instance of LoaderInfo, and LoaderInfo instances have a parameters property.  To update the above AS2 code, then, swap out the solitary audio variable with the expression root.loaderInfo.parameters.audio.  The name of the variable is the same, assuming FlashVars specifies it as “audio.”  Here it is in context:

var s:Sound = new Sound();
iconButton.onRelease = function():Void {
 s.loadAudio(root.loaderInfo.parameters.audio, true);
}

Now, even with that change, the above code would fail in ActionScript 3.0.  Why?  Because AS3’s event handler model is completely overhauled.  Button instances, like the above iconButton, no longer use onRelease as shown, plus the Sound class behaves differently.  Here’s the same brief code in AS3:

var s:Sound = new Sound();
iconButton.addEventListener(
 MouseEvent.MOUSE_UP,
 function(evt:MouseEvent):void {
  s.load(new URLRequest(root.loaderInfo.parameters.audio));
  s.play();
 }
);

But that isn’t the important part, because ultimately, what you do with passed-in variables is up to you.  The key is how to access them, and the solution is root.loaderInfo.parameters, followed by a dot and the name of whatever variable you’re after.  This variable will have been passed into Flash by way of the FlashVars attribute of your HTML’s <object> and/or <embed> tag(s).

20 Responses to “How to Retrieve FlashVars Data in ActionScript 3.0”

  1. Mikep Says:

    Nice article - I’m jumping into Flash starting at v.9, so the ActionScript 3.0 updates are appreciated.

    I looked at the earlier article as well, and I’m wondering if it’s possible to get the “value”(s) of the standard “param” tags passed in the HTML object/embed tag (or a Javascript call like AC_FL_RunContent/SWFObject), i.e. for

    <object [attributes] >
    <param name=”movie” value=”movie.swf” />
    <param name=”loop” value=”true” />

    in my .swf I’d see “movie” and its value “movie.swf”, “loop”/”true”, etc.

    I’ve run the following code:

    for ( var theName:String in root.loaderInfo.parameters ) {
    var theValue:String = root.loaderInfo.parameters [theName];
    trace( “Param: ” + theName + ” = ” + theValue );
    }

    and it echoes all my FlashVars name/values as you say, but I don’t see parameters passed to the Flash player itself. Thanks!

  2. David Stiller Says:

    Mikep,

    The result of your for..in loop makes sense, but I can hear what you’re saying. The thing is, those other attributes aren’t actually passed into the SWF. They’re attributes that affect Flash Player and the way it appears in the browser — the most important of which, arguably, is the name of which SWF to load. Keep in mind, too, that the <param> tags are specifically children of the <object> and interpreted as such. The <embed> tag, while usually a child of <object>, does stand on its own. The <object>/<param> entity and the <embed> entity each carries its own unique information, though most overlaps.

    Some of the information you’re after can be gleaned from other objects in the API. For example, the name of the SWF file itself could be derived from the MovieClip._url. property in AS2 when invoked on the main timeline. In AS3, this has been moved to the LoaderInfo.url property, which you can reach via the same root.loaderInfo property shown above. While not especially related to the HTML attributes in discussion, you’ll also find plenty about the environment in which Flash Player is spawned via the Capabilities class (was System.capabilities in AS2).

  3. anggie Says:

    David, I’ve just found your blog and I like your easy-to-read articles :-)

    Keep up the good work, man!

    BTW, would you mind if I translate some articles to my language ( Indonesian ) and post them to my blog ? I’ll provide a link back to your original article.

  4. David Stiller Says:

    anggie,

    I value variety in language and, in fact, speak only German with my daughter. I’d love to see these articles translated into Indonesian! :-D Make sure to send me the links to your work and I’ll update each article on this end with a reciprocal link to your translation.

  5. Craig Says:

    David,
    Once again, thanks so much for posting this for people like me who are just trying to get this particular thing to work.

    I was able to get this running on my WordPress blog with Kimili’s SWFObject plugin and one line of code in my flash swf of “flvControl.source = root.loaderInfo.parameters.flvSource;”.

    Thanks again!
    Craig

  6. David Stiller Says:

    Craig,

    Sure thing. Glad to help!

  7. Ben Says:

    Thanks TONS for mentioning the root.loaderInfo.parameters

    My movie wasn’t returning any of the flashVars I passed it until I simply assigned the root’s loaderInfo to the one I had declared:

    objLoaderInfo = root.loaderInfo

    After that, everything using my declared LoaderInfo worked as intended and I didn’t have to make any more code changes.

  8. David Stiller Says:

    Ben,

    Glad to hear it. :)

  9. getswfy » Blog Archive » ActionScript 3.0 FlashVars Says:

    […] In actionScript 3.0 FlashVars have changed.  In actionScript 2.0 you can simply access the variables from the root time line.  In actionScript 3.0 you now have to access the LoaderInfo Class.  David Stiller has a great article on all the changes. […]

  10. Nicole Says:

    So how do you stop the sound, because a new button with s.stop(); doesn’t seem to be working :)

  11. David Stiller Says:

    Nicole,

    In ActionScript 3.0, the Sound class doesn’t feature a stop() method like it does in AS2. To stop sound in AS3, you have to instantiate a SoundChannel instance and associate your Sound instance with that. Like this:

    var s:Sound = new Sound();
    var chan:SoundChannel;
    iconButton.addEventListener(
     MouseEvent.MOUSE_UP,
     function(evt:MouseEvent):void {
      s.load(new URLRequest(root.loaderInfo.parameters.audio));
      chan = s.play();
     }
    );
    stopButton.addEventListener(
     MouseEvent.MOUSE_UP,
     function(evt:MouseEvent):void {
      chan.stop();
     }
    );
  12. Adam Petrie Says:

    Is there any way to read in the value of the width and height parameters in the embed code?

    In AS 2.0 you could set the values in the embed code and then use Stage.height and Stage.width to read them in…. this has changed in AS 3.0 and I have tried desperately to find a solution.

    Know of anything? Cheers.

  13. David Stiller Says:

    Adam,

    FlashVars data (or query string data) enters the SWF via name/value pairs fed separately from the actual embed code. I think you’re asking if it’s possible to read the height and width attributes of the <object> and <embed> tags, right? If so, that isn’t possible in any version of ActionScript — again, unless you pass it in as a FlashVars variable.

    AS2’s Stage.width and Stage.height properties are now stage.stageWidth and stage.stageHeight in AS3. You can reference any DisplayObject instance, including the main timeline, to get your stage reference, and from there, check the properties mentioned. Does that help?

  14. Adam Petrie Says:

    You’re right, what Im asking is only similar in fashion to your original post, but you write intelligently so I thought I’d ask.

    Specifically, yes I do want to know if I can read the width and height attributes and until this afternoon, I’d agree with you that It was not possible to read them in any version of AS. Contrary to that a co-worker and I came up with an incredibly simple example that shows the swf being aware of those values in AS 2.0. Of course Im home now and the example is at work.

    Regardless, what I’m after is a way to resize my swf before runtime. I’ve created a widget that will be part of an online library where clients can customize and embed their widgets for their own use. I’d like to allow them to create a widget of any size.

    Do you know of any routes that will make this possible?

  15. David Stiller Says:

    Adam,

    Definitely, let me know about the example you put together with your co-worker! :) I’m curious to see what you found. My hunch is that you’re referencing the read-only Stage.width and Stage.height properties, which indeed return the width and height values of the Stage at the current moment. If you used pixel values in the width and height attributes of your <object> and <embed> tags, then those Stage properties will reflect the values of those attributes. On the other hand, it’s just as possible to use percentage values, which will allow the SWF to resize at runtime in response to the user resizing the browser. In that sort of scenario, those Stage properties (and their AS3 equivalents) will give you different numbers, depending on the current size of the SWF. In that way, you can tell the size of the Stage (i.e., the SWF), but it may or may not match the numbers specified in the HTML.

    Check out the Stage class in either version of ActionScript to see about using the onResize event. That will allow you to adjust the SWF’s width and height as you please — with pixels or percents — and then respond to those values at runtime.

  16. Adam Petrie Says:

    I think you are exactly correct in you explanation for the changes.

    The example was incredibly simple, but if you altered the values in the tags and set the width of a MovieClip to be equal to Stage.width, then when you opened the page in the browser, the MovieClip was resized appropriately.

    In fact that is exactly what I’d like to accomplish with AS3 because I have already written a function that resizes my UI on a FullScreenEvent so in essence all the code required is already there, I just need to figure out how (or where) to get the correct values from.

    I am going to begin playing with the AS3 equivalents right now. If you’d like a copy of that (incredibly rudimentary) example, feel free to e-mail me and I will send it over.

    Thanks for the input though, I’ve been racking my brain for a week now and as of yet, no one else on the net has been able to provide any input at all.

  17. David Stiller Says:

    Adam,

    Assuming you have a movie clip with the instance name box, the following would adjust the width and height of that movie clip to half the width and height of the Stage:

    stage.align = StageAlign.TOP_LEFT;
    stage.scaleMode = StageScaleMode.NO_SCALE;
    
    stage.addEventListener(
      Event.RESIZE,
      resizeHandler
    );
    
    function resizeHandler(evt:Event):void {
      box.width = stage.stageWidth / 2;
      box.height = stage.stageHeight / 2;
    }
  18. J Says:

    THANK YOU THANK YOU THANK YOU THANK YOU!!!!!!!!!!!!!!!!!!!!!!!

  19. David Stiller Says:

    J,

    Haha, you’re welcome! Glad I could help. :)

  20. Jasmin Auger Says:

    Hi David, sorry to bring an old post back to life, but I just wanted to tell you that the only way I have been able to pass an external variable to my SWF was to put them after the name of the swf in the js variable, and in the param and the embed tags. I’ve been searching over the internet for about 2 hours now and it seems it’s the only thing that works for me. I have a rather complex project, but I don’t understand why it doesn’t work using the FlashVars method… When using FlashVars, the variables are simply not passed and I get a “url parameter must be non-null” error.

    Here are the 3 var I had to change:

    In the AC_FL_RunContent script:

    ‘movie’, ‘gallery?menuName=xml/MenuAng.xml&pictureName=xml/Pictures.xml’,

    In the param tag:

    and in the embed tag:

    src=”gallery.swf?menuName=xml/MenuAng.xml&pictureName=xml/Pictures.xml”

    Hope this might help other people!

Leave a Reply