Strongly Typed FlashVars and Robotlegs

Posted 1 August 2010 by

Don’t we all wish there is a easy way to strongly type and default flashvars, well here is a solution that will provide you with that and a bit more.

For those of you that like looking at source code while reading:

What are these “flashvars” ?!?

By “flashvars” I mean the parameters you pass to your flash application via the embedding code. These are provided to flash in the form of query variables and are parsed internally by the flash player. Flashvars are made available to you via the stage/root instance’s loaderInfo object. The loaderInfo’s parameters property is a dynamic Object that contains the flashvars passed.

Quick Overview:

  • Create a new class FlashVars class that extends the FlashVarsDynamic class for each project.
  • Create public variables in your FlashVars class with default values.
  • Embed your swf on a html page that passes the real values via the embedding code.

The FlashVarsDynamic class:

This will be the base class of your FlashVars class, it’s a dynamic class which means it can contain properties created at run time. It handles the parsing of the parameters Object and casts the values into their respective types. It works by assigning the flashvars you pass to it, onto its self. This is why it’s important that you extend this class for each project you create, because once you extend it inherits the functionality, but isn’t dynamic any more. So when it wants to place the flashvas onto its self, it overwrites your default values with the ones you are passing from the embedding code.

package mu.utils
{
	import flash.utils.unescapeMultiByte;

	/**
	 * @author Matan Uberstein
	 *
	 * FlashVarsDynamic class should be extended to a specific representation of what is required by
	 * the new application/webiste. Simply extend the FlashVarsDynamic and add public accessors and they
	 * will be automatically be populated by the embedded flashvars passed.
	 */
	public dynamic class FlashVarsDynamic
	{

		/**
		 * Evaluates Flash vars, converts strings to specified data type.
		 *
		 * @param params LoaderInfo parameters Object.
		 * @param unescapeValues Boolean, unescapeMultiByte is used if true.
		 *
		 * Type prefix must be separated by underscore "_"
		 * 	<code>	Javascript:
		 * 			var params = {boolean_isLoggedIn:true, array_playerNames:"Matan,Luke,John"};
		 *
		 * 			Flash:
		 * 			var _flashvars : FlashVars = new FlashVars(this.stage.loaderInfo.parameters);
		 * 			trace(_flashvars.isLoggedIn);			//true
		 * 			trace(_flashvars.playerNames);			//Matan, Luke, John
		 * 			trace(_flashvars.playerNames is Array);	//true
		 * 	</code>
		 */
		public function FlashVarsDynamic(loaderInfoParams : Object, unescapeValues : Boolean = false)
		{
			parse(loaderInfoParams, unescapeValues);
		}

		/**
		 * Override this to catch parsing errors.
		 */
		protected function onParseError(key : String, value : String, error : Error) : void
		{
		}

		/**
		 * Override this to change the unescaping function and/or change value before it's parsed.
		 *
		 * @return String
		 */
		protected function getValue(object : Object, key : String, unescapeValue : Boolean) : String
		{
			return unescapeValue ? unescapeMultiByte(object[key]) : object[key];
		}

		protected function parse(params : Object, unescapeValues : Boolean = false) : void
		{
			var types : Array = new Array("array", "boolean", "int", "number");

			for(var key : String in params)
			{
				var value : String = getValue(params, key, unescapeValues);

				var keySplit : Array = key.split("_");
				var type : String = keySplit[0].toLowerCase();
				var typeIndex : int = types.indexOf(type);

				if(typeIndex != -1)
					key = keySplit.splice(1).join("_");

				try
				{
					switch (type)
					{
						case "array" :
							this[key] = value.split(",");
							break;
						case "boolean" :
							this[key] = toBoolean(value);
							break;
						case "int" :
							this[key] = int(value);
							break;
						case "number" :
							this[key] = Number(value);
							break;
						default :
							this[key] = value;
							break;
					}
				}catch(error : Error)
				{
					onParseError(key, value, error);
				}
			}
		}

		protected function toBoolean(str : String) : Boolean
		{
			str = str.toLowerCase();
			if(str == "1" || str == "true")
				return true;
			return false;
		}
	}
}

Creating your custom FlashVars class:

A good place to put your FlashVars is in a “utils” package, so create a class called FlashVars that extends FlashVarsDynamic and save it there. Now adding the FlashVars is easy, just keep on adding public variables to this class as you need it and remember to add your default values for testing.

Use with Robotlegs:

Add the [Inject] metadata tag above your constructor, specify one parameter contextView : DisplayObjectContainer and call super(contextView.stage.loaderInfo.parameters); .

In your Context you can make the mapping as you choose, but mostly you’ll need a singleton: injector.mapSingleton(FlashVars);

The contextView will be injected into this FlashVars instance once it’s instantiated and the parameters will be parsed by the super.

package sample.utils
{
	import flash.display.DisplayObjectContainer;

	import mu.utils.FlashVarsDynamic;

	/**
	 * @author Matan Uberstein
	 */
	public class FlashVars extends FlashVarsDynamic
	{
		public var heading : String = "Default Mode Running, no flash vars passed via embedding.";

		public var sessionId : String = "session-id-default";
		public var isLoggedIn : Boolean = false;
		public var userNames : Array = ["TestName1","TestName2","TestName3"];
		public var someNumber : Number = 2.5;
		public var userId : int = 0;

		[Inject]

		public function FlashVars(contextView : DisplayObjectContainer)
		{
			super(contextView.stage.loaderInfo.parameters);
		}
	}
}

Passing values to flash from html:

For the strongly typed flashvars, prefix your flashvar name with the type, followed by an underscore and then your flashvar name. Note these prefixes are removed during parsing. Acceptable prefixes are:

  • array (comma delimiter)
  • boolean
  • number
  • int

The JavaScript Object below will be passed to flash via SWFObject. Note the variable naming:

//FlashVars
var _v = {};
_v.heading = "Browser Mode Running, flash var values passed from embedding.";
_v.sessionId = "WQERFDSADF-XS-MSDFKITYCJ";
_v.boolean_isLoggedIn = true;
_v.array_userNames = ["Matan","Marvin","Francis"];
_v.number_someNumber = 54.387;
_v.int_userId = 880104;

Why go through all this trouble?

  • Run the swf independent without the html embedding code.
  • Debugging becomes easier and your flashvar parsing is central.
  • You don’t have to manually check if the parameter exists.
  • Adding parameters are quick and easy.
  • Simple values are pre-cast.

Sample Robotlegs implementation source:

Run the swf independently and then run the index.html to see the difference.

Post Details

  • http://varga-multimedia.com Francis Varga

    Hahahahaha nice example with our name :D #iLike

  • http://www.studentgrantshelp.org student grants

    nice post. thanks.

  • http://www.wouterschreuders.com Wouter Schreuders

    Nice dude! dit het my gered

    • http://doesflash.com Matan Uberstein

      It’s thanks to you that I made this post. :) After I helped you with your flashvars issue, I thought this would make a nice post.

  • http://www.pedrovalentim.net Pedro Valentim

    Really clever solution man, I’ll be using this for sure :)

    • http://doesflash.com Matan Uberstein

      Great! Always good to get positive feedback!

      Thanks for the comment! :D

  • Pingback: AssetLoader Robotlegs Tutorial | Matan Uberstein | AS3 Blog

  • Ivan

    I’m pretty much new to Robotlegs, and I have one question:
    Why are you Adding the [Inject] metadata tag above the constructor in the FlashVars class

    • http://doesflash.com Matan Uberstein

      Hi Ivan,

      Robotlegs automatically has a DisplayObjectContainer mapped, usually this is an instance of the Stage, which means that you can access the loaderInfo’s parameters (the flashvars). When we create a mapping on the “injector” in our context, Robotlegs will instantiate the FlashVars class once we need it somewhere, by doing so all the [Inject] points on FlashVars will be satisfied. Thus the “stage” is automatically passed to our FlashVars instance.

      Probably could have said that better ;-) but I hope you understand.

      Thanks for the comment! :D

  • Ivx

    Great class Matan !
    What is the licence for this class?
    Can it be used in commercial products?

    • http://doesflash.com Matan Uberstein

      :D Thanks! You are free to do with it what you want! Let me know how it goes, maybe there are some improvements to be done.

      • Ivx

        Thanks!
        I will be using your class with Google maps flash API (passing data to it )
        I’ll let you know how it goes :)

  • http://zerodtkjoe@gmail.com zerodtkjoe

    Thanks for the info

  • Pingback: AssetLoader Robotlegs Tutorial | Does Flash | AS3 Blog