Converting a JSFL Object to JSON
I couldn’t find any online resource to talk about how people are passing data from JSFL scripts to their Flash Panels. When you use MMExecute you can return a String value back to Flash, or if you’re making a function available via ExternalInterface you can also pass primitive datatypes into the functions. However when you start talking about passing Objects of any significant structure, things get a little hairy.
So it was my conclusion that I needed to serialize my data object in JSFL in order to pass it to Flash. And when you talk serialize in Javascript you should think JSON, so I set in search for an out-of-the-box Javascript Object to JSON serializing function - should be easy to find right? Unfortunately, after two days of struggling with different implementations, I found that some of the String functions like match and replace cause errors (not saying they aren’t implemented, just for whatever reason they didn’t work for me like they do in regular JS).
So without further delay, here is my very less-than perfect, less-than optimized JSFL Object to JSON String functions. (Also note that these will convert any Arrays nested in your Objects to Objects themselves with keys being the string equivalent of their indexes.
— UPDATE —
I wrote this post before testing it completely against sending the JSON string over to Flash via the SWFPanel.call() method. What I found out while trying to do this is that you can not, for whatever reason, send literal single or double quotes embedded within the string variable. So I changed up my function to use tildes (~) instead of quotes, which I then replaced with quotes over on the AS3 side of things.
function serializeObject( o ) {
var s = '{';
s += so( o );
//remove the last comma
s = s.slice( 0, s.length-1 );
s += '}';
return s;
}
function so( o ) {
var s = '';
for( var key in o ) {
if( o[key].toString() == '[object Parameter]' ) {
s += '~' + key + '~:{';
s += so( o[key] );
//remove the last comma
s = s.slice( 0, s.length-1 );
s += '},';
} else if(o[key].constructor === Array ) {
for( var key2 in o[key] ) {
if(key2 != "" && o[key][key2].value != '""') {
s += '~' + key2 + '~:~' + o[key][key2].value + '~,';
}
}
}else {
if(key != "" && o[key] != '""') {
s += '~' + key + '~:~' + o[key].toString() + '~,';
}
}
}
return s;
}
And here is what I do on the AS3 side to convert it into an Object from JSON (note I’m using the as3corelib to JSON decode the string).
//function exposed via ExternalInterface and called from JSFL
public function setParameters( s:String ):void {
var p:RegExp = /~/g;
var t:String = s.replace(p, '"');
var o:Object = JSON.decode(t);
}
Like I said it’s not a perfect implementation, but it works pretty well for nested Objects. To put this in perspective, I’m using this so I can pass all the attributes of multiple selected components on the stage (via the fl.getDocumentDOM().selection Array) to my WindowSWF Panels which will allow me to change and configure the components’ properties.