Passing complex objects via FlashVars using native JSON

As the title states, this post shows how to pass a complex object to flex via FlashVars using native JSON on both Javascript and ActionScript side. Consider the following fairly complex JavaScript object defined using literal notation:

var flashvars = {
	name: "user1",
	type: "2",
	loggedIn: "true",
	filesList: {
		path: "www.files.com/files/",
		files: [
			{label: 'File0', name: "file0.txt"},
			{label: 'File1', name: "file1.txt"},
			{label: 'File2', name: "file2.txt"},
			{label: 'File3', name: "file3.txt"},
			{label: 'File4', name: "file4.txt"}
		]
	}
};

As flashvars are always treated as strings by passing the object in the above, you won’t be able to access the filesList  property on the flex side. There are other supported methods to get around this limitation (such as ExternalInterface calls or just passing a simple URL, and then based on that in flex make call to that URL to fetch the complex object), but they do not make the object of this post. So the other way is to use serialization (the process of transforming an Object(s)/values into a String) and deserialization (transform the string back into an Object(s)/values). The preferred string notation in JavaScript is obviously JSON. All modern browsers support native JSON, and most popular Javascript  libraries makes use of it if available or implement their own support. There are 2 methods available for serialization/deserialization:

//serializer
JSON.stringify(value [, replacer [, space]]) — converts an JavaScript object/value to a JSON string
//deserializer
JSON.parse(text [, reviver]) — converts a JSON string back to a JavaScript object/value

I am only interested in serializing the filesList property of the flashvars object since the other properties are primitives and can be passed as they are. Modified code follows:

var flashvars = {};
flashvars.name = "user1";
flashvars.type = "2";
flashvars.loggedIn = "true";

var filesList = {
	path: "www.files.com/files/",
	files: [
		{label: 'File0', name: "file0.txt"},
		{label: 'File1', name: "file1.txt"},
		{label: 'File2', name: "file2.txt"},
		{label: 'File3', name: "file3.txt"},
		{label: 'File4', name: "file4.txt"}
		]
};

var newList = JSON.stringify(filesList);
//some IE versions URLEncodes different than the other browsers
//to be on the safe side call encodeURIComponent() on the JSON encoded string
flashvars.filesList = encodeURIComponent(newList);

On the receiving flex side if you are lucky enough to target a flash player version greater or equal to 10.3, you will benefit from the native JSON support. Methods signatures are identical to their JavaScript  counterparts. Code to deserialize the Object is listed below:

//get the fileList object
var files:Object = JSON.parse(parameters.filesList);
//get the files array
var list:Array = files.files;

//output content
trace("path = ", files.path);
for (var i:int = 0; i < list.length; i++)
{
	trace ("list[" + i + "] = {label = " + list[i].label + ", name = " + list[i].name + "}");
}

And the trace will output:

path =  www.files.com/files/
list[0] = {label = File0, name = file0.txt}
list[1] = {label = File1, name = file1.txt}
list[2] = {label = File2, name = file2.txt}
list[3] = {label = File3, name = file3.txt}
list[4] = {label = File4, name = file4.txt}

Easy as that!

P.S.

Same technique can be employed to serialize complex ActionScript objects when written to disk as SharedObject(s).

One Comment

Leave a Reply

Your email address will not be published. Required fields are marked *

*