I have tried to write an utility function that can convert my custom data (data Sencha Touch stores use) to JSON format and I am almost done but it fails with complex data coming from twitter API but works fine with simple type of data.
Custom Data
var items = [];
for (var i = 0; i < 10; i++) {
var item = {};
var data = {};
data.prop1 = "123456789";
data.prop2 = "Some Name";
data.prop3 = "Some Date and Time";
item.data = data;
items.push(item);
}
Now above data can be accessed in a loop and can be converted to JSON with following function.
function toJSON(items) {
var jsonString = "[";
for (var i = 0; i < items.length; i++) {
var item = items[i];
jsonString += "{";
for (var propertyName in item.data) {
jsonString += '"' + propertyName + '":' + '"' + item.data[propertyName] + '",';
}
if (jsonString.substr(jsonString.length - 1, 1) === ",") {
jsonString = jsonString.substr(0, jsonString.length - 1);
}
jsonString += "},";
}
if (jsonString.substr(jsonString.length - 1, 1) === ",") {
jsonString = jsonString.substr(0, jsonString.length - 1);
}
jsonString += "]";
return jsonString;
}
The question is if I am doing the encoding thing right?
You can see these fiddle to get real time experience http://jsfiddle.net/WUMTF/ and http://senchafiddle.com/#gxtZ9
Is there any reason why you don't just use the native JSON.stringify() method, or the (wrapped) versions provided by your favorite JavaScript / AJAX library? They will be more robust, tested, secure, and better performing. (Most of the library versions will simply call the browser's native methods if available.)
Your toJSON implementation may be working for your simple test data, but is failing for more complex types of data for many reasons, but most probably most significantly, because it fails to account for any type of nesting. It assumes that the top level is always an array, and that each element in the array only has properties one level deep. Take a look at https://github.com/douglascrockford/JSON-js/blob/master/json.js . This is the implementation provided by Douglas Crockford, the "father" of JSON. Pretty much everything shown there is required for a valid implementation. Unfortunately, the odds are against you if you think that you can easily and simply recreate this in a short amount of time (short of copy and paste).
Related
I need to send an email that contains the console.log output of a JS object. Here a code example:
let array_multi = [];
array_multi["07:00"] = ["one","two","three"];
array_multi["08:00"] = ["foo","bar","foo"];
array_multi["09:00"] = ["lorem"];
console.log(array_multi);
In my console result like this:
Is there some method to get this output in plain text, or should I write a custom parsing function?
If you are using JSON.stringify, you'll get the complete data, however there are a few downsides:
Arrays string properties, functions and other data structures get ignored completely (therefore serializing your data as is won't work¹)
circular references fail to serialize
There is no way to see inheritance from that
In your case you could do:
let array_multi = {};
array_multi["07:00"] = ["one","two","three"];
array_multi["08:00"] = ["foo","bar","foo"];
array_multi["09:00"] = ["lorem"];
// logs as object
console.log(array_multi);
console.log(typeof array_multi);
// parse and convert to string
console.log(JSON.stringify(array_multi));
console.log(typeof JSON.stringify(array_multi));
In Node.js you've got another option, which is util.format, which will return the same content as a string that you can see in the Node.js console. While it does give you a great insight into the different datatypes and relationships, it cannot show you the same infinite tree that an interactive console is able to show, so it will only show you a small part of the big picture.
¹: Your array_multi should actually be an object, not an array, as arrays should only have numeric keys.
After a lot of search the right method is write a custom function (chrome have once inside dev tools core)
here the solution:
let array_multi = [];
array_multi["07:00"] = ["one","two","three"];
array_multi["08:00"] = ["foo","bar","foo"];
array_multi["09:00"] = ["lorem"];
function print_js_element(elm, show_content = false){
let output_res = "{\n";
let object_keys = Object.keys(elm);
object_keys.some(function(key,index) {
output_res += "\t" + key + ": (" + elm[key].length + ")";
if(show_content){
output_res += " " + JSON.stringify(elm[key]);
}
output_res += "\n";
});
output_res += "\n}";
return output_res;
}
console.log(print_js_element(array_multi,false));
console.log(print_js_element(array_multi,true));
Covert this array into an object first:
let array_multi = [];
array_multi["07:00"] = ["one","two","three"];
array_multi["08:00"] = ["foo","bar","foo"];
array_multi["09:00"] = ["lorem"];
let arrObj = {...array_multi};
console.log(JSON.stringify(arrObj));
I get the following json data from server.
{"visits":[{"City":6,"Count":5},{"City":16,"Count":1},{"City":23,"Count":1},{"City":34,"Count":1}]}
and i need to convert it to following format:
{"1":"82700","2":"26480","3":"31530","4":"22820","5":"15550","6":"205790"}
I have the following code but not working out:
var cities = "{";
for (var key in data.visits) {
var val = data.visits[key];
//Now you have your key and value which you
//can add to a collection that your plugin uses
var obj = {};
obj[val.City] = '' + val.Count;
var code = '' + val.City;
var count = '' + val.Count;
cities += code + ':' + count + ',';
}
cities += "}";
I need the integers in string representation and need to get rid of the final , .
How can i fix this?
Try this
var data = {"visits":[{"City":6,"Count":5},{"City":16,"Count":1},{"City":23,"Count":1},{"City":34,"Count":1}]};
var result = {};
for (var i = 0; i < data.visits.length; i++) {
result[data.visits[i].City] = String(data.visits[i].Count);
}
Example
Keys in object always converts to string you don't need convert it to string manually. If you need convert all object to JSON string you can use JSON.stringify(result);
How I understood you want to create new json with given json.you can parse it,run with cycle on it,and create a new json whatever kind of you want.
here is a link which can help you.
http://www.w3docs.com/learn-javascript/working-with-json.html
I am trying to get rid of the jQuery dependency in a project. One thing that project does is posting data to a server like so:
var data = {"apple": [{"kiwi": "orange"}, {"banana": "lemon"}], "pear": "passion fruit"};
$.post( url, data);
Thanks to You might not need jQuery, I know how to rewrite $.post in pure Javascript using XMLHttpRequest:
var request = new XMLHttpRequest();
request.open( 'POST', url, true);
request.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
request.send( data);
Unfortunately, this description seems to assume that the data object is already a URL-encoded query string, which is clearly not the case in the above example. It turns out jQuery does more than that: With the given data object, the above $.post call would first convert it to a query string, which would look like so:
apple%5B0%5D%5Bkiwi%5D=orange&apple%5B1%5D%5Bbanana%5D=lemon&pear=passion+fruit
The code snippet using XMLHttpRequest does not do so, and, thus, the server will throw errors at me.
jQuery also has a wonderful method call $.param which does exactly this conversion. The above code snippet using XMLHttpRequest will work marvelously if in the last line I do
request.send( $.param(data));
But then, I did not get rid of the jQuery dependency. So I'm looking for a pure Javascript equivalent of $.param. Does anyone have something like that?
Note: The question Plain Javascript Equivalent of jQuery.param() asks a similar question, but the accepted answer only works in very simple cases. Applying the function given in that answer to my above data object yields:
apple=%5Bobject%20Object%5D%2C%5Bobject%20Object%5D&pear=passion%20fruit
...which is obviously different from the result of $.param(data) given above, and loses information since it doesn't work recursively.
I have made a quick function for you which should achieve this for you, it will create parameters from your key=>value pairs and stringify your non primitive values.
var objToParams = function(obj){
var paramString = '';
for (var key in data) {
var value = obj[key];
if(obj[key] instanceof Array || obj[key] instanceof Object){
value = encodeURIComponent(JSON.stringify(value));
}
if (paramString != "") paramString += "&";
paramString += key + "=" + encodeURIComponent(value);
}
return paramString;
}
var data = {"apple": [{"kiwi": "orange"}, {"banana": "lemon"}], "pear": "passion fruit"};
console.log(objToParams(data));
http://jsfiddle.net/7buy3rjy/
Edit, from your comment this should work and is now matching the output of $.param:
http://jsfiddle.net/mg511z7w/
var data = {"apple": [{"kiwi": "orange"}, {"banana": "lemon"}], "pear": "passion fruit"};
var stringifyParam = function(data, topLevel, keyProp) {
var string = '';
for (var key in data) {
if(keyProp && topLevel[keyProp] ) {
if ( (topLevel[keyProp] instanceof Array&&topLevel[keyProp].indexOf(data[key])!==0) ) {
string += keyProp;
} else if ( (topLevel[keyProp] instanceof Object&&topLevel[keyProp][key]) ) {
string += keyProp;
}
}
if (typeof(topLevel[key])=='undefined') {
string += '[' + key + ']';
}
if (data[key] instanceof Array) {
string += stringifyParam(data[key], topLevel, key);
} else if(data[key] instanceof Object){
string += stringifyParam(data[key], topLevel, key);
} else {
if (typeof(topLevel[key])!='undefined') {
string += key;
}
string += '=' + data[key];
string += '&';
}
}
return string;
},
toParam = function(data){
var string = stringifyParam(data,data);
return encodeURI(string.substring(0,string.length-1).split(' ').join('+'));
};
console.log(toParam(data)); //apple%5B0%5D%5Bkiwi%5D=orange&apple%5B1%5D%5Bbanana%5D=lemon&pear=passion+fruit
console.log($.param(data)); //apple%5B0%5D%5Bkiwi%5D=orange&apple%5B1%5D%5Bbanana%5D=lemon&pear=passion+fruit
You could go about doing recursive code but why not try the simple scheme JSON, which was why it was created - To exchange data between client and server in an easier manner.
Just do this
request.send(JSON.stringify(data));
JSON.stringify accepts an Object which will then be converted to a valid JSON, which can be parsed in the server-side.
To know more about the JSON, there can't be a better way than going through it's tag excerpt here
you could use encode and decode URIComponent functions to accomplish this.
edit
what about this:
var qs = Object.keys(obj).reduce(function(a,k){
a.push(k+'='+encodeURIComponent(JSON.stringify(obj[k])));
return a;
},[]).join('&');
// "apple=%5B%7B%22kiwi%22%3A%22orange%22%7D%2C%7B%22banana%22%3A%22lemon%22%7D%5D&pear=%22passion%20fruit%22"
instead of this:
var obj = {"apple": [{"kiwi": "orange"}, {"banana": "lemon"}], "pear": "passion fruit"};
var data = encodeURIComponent(JSON.stringify(obj));
// "%7B%22apple%22%3A%5B%7B%22kiwi%22%3A%22orange%22%7D%2C%7B%22banana%22%3A%22lemon%22%7D%5D%2C%22pear%22%3A%22passion%20fruit%22%7D"
var obj2 = JSON.parse(decodeURIComponent(data));
// {"apple":[{"kiwi":"orange"},{"banana":"lemon"}],"pear":"passion fruit"}
This question already has answers here:
How to store objects in HTML5 localStorage/sessionStorage
(24 answers)
Closed 8 years ago.
I have several large multi-dimensional arrays that I'm saving to local storage. They look like this:
[[[-150],[0],[-650],0],[[-100],[0],[-650],0],[[-50],[0],[-650],0] ... ]
The data is '4D' data. When I try loading this 'string' into an array in another JS (in separate html), it doesn't behave like an array- it's only a string.
Here's how I load the data back into the second JS (not sure why the loop didn't work either):
var lay= new Array();
//for(var g=0;g>=9;g++)
//{ lay[g] = localStorage.getItem("key" + g);
// console.log(lay[g]);
//}
lay[0] = localStorage.getItem("key0");
lay[1] = localStorage.getItem("key1");
lay[2] = localStorage.getItem("key2");
//... more here
lay[9] = localStorage.getItem("key3");
After I load this "4D" info into the array, I pull the info out to use it:
var count=0;
var len=0;
for (y=0;y<=1;y++)
{ console.log(lay[y]);
count=1;
len = lay[y].length;
for (x=1;x<=len-1;x++)
{
Rx = lay[y][count][0];
Ry = lay[y][count][1];
Rz = lay[y][count][2];
Rcolor = lay[y][count][3];
When I add this to the code console.log(len); I get the length of characters in the array, not the number of elements. How can I get the data from local storage to come in and behave like array? I thought that the formatting alone would get it behave like an array.
Do I need to parse it back into an array again? If so, I'm guessing I should just output the data in a simpler format to parse it again...
Thanks for the help!
Edit
Here's how I made the local storage:
for (var a=0;a<=14;a++)
{ updateTemp(tStep + a);
$("#temp tbody tr").each(function(i, v){
data[i] = Array();
$(this).children('td').each(function(ii, vv){
data[i][ii] = $(this).text();
rows=ii;
cols=i;
});
});
retval="";
for (var q=0;q<=cols;q++)
{
for (var w=0;w<=rows;w++)
{
var tempv = data[q][w];
var tX = w*50 - 1000;
var tY = 1*50 - 50;
var tZ = q*50 - 1000;
if (tempv==-9){
(dummy=q*w);
}
else {retval += tX +',' + tY + ',' + tZ + ',' + tempv + ',';}
}
}
var kee = "key" + a;
retval = retval.substring(0, retval.length-1); //this is to get rid of the last character which is an extra ,
window.localStorage.setItem(kee, retval);}
JSON encode the array before storing, parse after retrieving.
localStorage.test = JSON.stringify([1,2,3]);
console.log(JSON.parse(localStorage.test));
This is a duplicate of “Storing Objects in HTML5 localStorage”. localstorage only handles strings. As suggested there, serialise your array to a JSON string before storing.
I have an XML response from server (SOAP) and I'm getting multiple values in it. XPath extracts all the values and stores them internally like Match_1, Match_2, Match_3, etc.
But I can't access them neither via BSF Post Processor nor via JavaScript code pasted in XML. It just refuses to return values then I address to them like this: ${Match_1}.
Example:
Response returns multiple contentGroupID values.
Debug Sampler reveals them:
contentGroupID=67
contentGroupID_1=67
contentGroupID_2=50
contentGroupID_3=38
contentGroupID_4=54
contentGroupID_5=46
We need to use each of these values in the next single request, so we add a code inside XML in place where we need those values to sit:
${__javaScript
(myOutput =''; var names = {};
for (var i = 1; i <= ${contentGroupID_matchNr}; i++)
{names[i] = "${contentGroupID_" + i + "}";}
for (var j = 1; j <= ${contentGroupID_matchNr}; j++)
{myOutput =
myOutput + '<ns8:forContentGroupId><ns2:id>' + names[j] + '</ns2:id></ns8:forContentGroupId>';},
myOutput)
}
Here we place the part of XML with values <ns8:forContentGroupId><ns2:id>' + ids + '</ns2:id></ns8:forContentGroupId> as many times as matches were found by XPath.
But the magic does not happen. The request is sent as follows:
<ns8:forContentGroupId><ns2:id>${contentGroupID_1}</ns2:id></ns8:forContentGroupId>
<ns8:forContentGroupId><ns2:id>${contentGroupID_2}</ns2:id></ns8:forContentGroupId>
<ns8:forContentGroupId><ns2:id>${contentGroupID_3}</ns2:id></ns8:forContentGroupId>
<ns8:forContentGroupId><ns2:id>${contentGroupID_4}</ns2:id></ns8:forContentGroupId>
<ns8:forContentGroupId><ns2:id>${contentGroupID_5}</ns2:id></ns8:forContentGroupId>
The same happens in case I set BSF Post Processor with JavaScript code and add a variable in XML.
The question is: how the hell can one access those magical values?
P.S. Everything works great then I use ForEach Controller. But the trick is I need to make single request with all the values, not multiple requests one after another.
Found the solution here:
BSF Post Processor witch JavaScript code:
var myOutput = '';
var names = {};
var str;
var value = 0;
var match = vars.get("contentGroupID_matchNr");
for (var i = 1; i <= match; i++)
{
var n = i.toString();
str = 'contentGroupID_' + n;
value = vars.get(str);
names[i] = value;
}
for (var j = 1; j <= match; j++) {
myOutput = myOutput + '<ns8:forContentGroupId><ns2:id>' + names[j] + '</ns2:id></ns8:forContentGroupId>';
}
vars.put("array", myOutput);
Plus ${array} variable inside XML.
End of story! =)