PDA

View Full Version : Useful way to serialize complex objects and arrays...



violinista
13 Jul 2007, 6:20 AM
Hello folks, I found an useful way to serialize objects and applied, with slightly modifications, to our lovely Ext.

First, to define problem: in some (rare, but real!) cases, you want to pass complex object or multi-dimension arrays to server-side. For example, if you want to pass this object:

{foo:'bar'}...it'll be encoded as:

foo=barBut, what if you want to pass object like this:

{foo:['bar1','bar2']}To get this object properly, it must be encoded like this:

foo[]=bar&foo[]=bar2That is the point, and I found here (http://www.openjs.com/scripts/data/ued_url_encoded_data/) useful method which works for me.
The urlEncode-advanced function in Ext, which works good so far (for me), but - I suppose so - could be much improved and more optimized is:



Ext.apply(Ext,{

urlEncode:function(arr,current_index) {

if(!arr){
return "";
}
var query = ""
if(typeof current_index=='undefined') current_index = '';

if(typeof(arr) == 'object') {
var params = new Array();
for(key in arr) {
var data = arr[key];
var key_value = key;
if(current_index) {
key_value = current_index+"["+key+"]"
}

if(typeof(data) == 'object') {
if(data.length) { //List
for(var i=0;i<data.length; i++) {
params.push(key_value+"[]="+this.urlEncode(data[i],key_value)); //:RECURSION:
}
} else { //Associative array
params.push(this.urlEncode(data,key_value)); //:RECURSION:
}
} else { //String or Number
params.push(key_value+"="+encodeURIComponent(data));
}
}
query = params.join("&");
} else {
query = encodeURIComponent(arr);
}
return query;
} });
As stated in the link before, now you can do something like:


var arr = {
'name':"Violinista",
'year':2007,
'quote':"Hello, World!",
'os':['Windows','Linux','Mac'],
'software':{
'editor':"vi",
'audio':"xmms",
'video':"vlc"
}
}
console.log(Ext.urlEncode(arr));Note that comments and improvements are much appreciated.

Note: I needed this stuff as I'm writing some king of query-by-example form (which will be presented here when finished!), and that kind of form sends much complicated information to server-side, when reloading datagrid with its parameters. This way, I can add to ds.load all the params I need and it is done on ExtJs standard way.

Regards :)

Wolfgang
17 Jul 2007, 4:21 AM
Hello,

why do you not use JSON?

Regards

Wolfgang

violinista
17 Jul 2007, 5:25 AM
I don't know the other way to serialize object and send it as JSON via GET or POST request.

JeffHowden
17 Jul 2007, 9:59 PM
I agree, urlEncode and urlDecode are for encoding and decoding valid name/value pairs as you'd find in a URL. That PHP has made special cases for certain characters being a part of the name portion of the pair causing arrays to be generated doesn't necessarily mean it has to be supported in a pure url encoding/decoding method in Ext. Simply, the urlEncode and urlDecode are for working with simple name/value pairs.

If you want to pass complex data back and forth, use JSON, that's what it's for. Pass an object of any manner of complexity to Ext.util.JSON.encode() and you'll get back a JSON string. If you receive a JSON string from the server, pass it to Ext.util.JSON.decode() and you'll receive back an object of appropriate complexity.

violinista
19 Jul 2007, 4:55 AM
Ok, suppose I have datagrid with dataset accepting complex object in need to produce WHERE condition properly. With this tool I can do simply:
ds.load({params:myComplexObject})
...and all params will be passed correctly. As simple as that. Note:I have more than 10 arrays of complex parameters to pass to my Db. If someone knows more elegant way to solve this, I will appreciate to see it.
Greetz, Violinista

JeffHowden
19 Jul 2007, 8:33 PM
I already outlined precisely how to do it. Using JSON, you know server-side when you deserialize the JSON string which portions are objects, which are arrays, and which are simple values. Even better, there are tools available in nearly application server language to decode or deserialize JSON strings meaning you don't need to do any manual coding to convert them.