Convert javascript object or array to json for ajax data - javascript

So I'm creating an array with element information. I loop through all elements and save the index. For some reason I cannot convert this array to a json object!
This is my array loop:
var display = Array();
$('.thread_child').each(function(index, value){
display[index]="none";
if($(this).is(":visible")){
display[index]="block";
}
});
I try to turn it into a JSON object by:
data = JSON.stringify(display);
It doesn't seem to send the proper JSON format!
If I hand code it like this, it works and sends information:
data = {"0":"none","1":"block","2":"none","3":"block","4":"block","5":"block","6":"block","7":"block","8":"block","9":"block","10":"block","11":"block","12":"block","13":"block","14":"block","15":"block","16":"block","17":"block","18":"block","19":"block"};
When I do an alert on the JSON.stringify object it looks the same as the hand coded one. But it doesn't work.
I'm going crazy trying to solve this! What am I missing here? What's the best way to send this information to get the hand coded format?
I am using this ajax method to send data:
$.ajax({
dataType: "json",
data:data,
url: "myfile.php",
cache: false,
method: 'GET',
success: function(rsp) {
alert(JSON.stringify(rsp));
var Content = rsp;
var Template = render('tsk_lst');
var HTML = Template({ Content : Content });
$( "#task_lists" ).html( HTML );
}
});
Using GET method because I'm displaying information (not updating or inserting). Only sending display info to my php file.
END SOLUTION
var display = {};
$('.thread_child').each(function(index, value){
display[index]="none";
if($(this).is(":visible")){
display[index]="block";
}
});
$.ajax({
dataType: "json",
data: display,
url: "myfile.php",
cache: false,
method: 'GET',
success: function(rsp) {
alert(JSON.stringify(rsp));
var Content = rsp;
var Template = render('tsk_lst');
var HTML = Template({ Content : Content });
$( "#task_lists" ).html( HTML );
}
});

I'm not entirely sure but I think you are probably surprised at how arrays are serialized in JSON. Let's isolate the problem. Consider following code:
var display = Array();
display[0] = "none";
display[1] = "block";
display[2] = "none";
console.log( JSON.stringify(display) );
This will print:
["none","block","none"]
This is how JSON actually serializes array. However what you want to see is something like:
{"0":"none","1":"block","2":"none"}
To get this format you want to serialize object, not array. So let's rewrite above code like this:
var display2 = {};
display2["0"] = "none";
display2["1"] = "block";
display2["2"] = "none";
console.log( JSON.stringify(display2) );
This will print in the format you want.
You can play around with this here: http://jsbin.com/oDuhINAG/1/edit?js,console

You can use JSON.stringify(object) with an object and I just wrote a function that'll recursively convert an array to an object, like this JSON.stringify(convArrToObj(array)), which is the following code (more detail can be found on this answer):
// Convert array to object
var convArrToObj = function(array){
var thisEleObj = new Object();
if(typeof array == "object"){
for(var i in array){
var thisEle = convArrToObj(array[i]);
thisEleObj[i] = thisEle;
}
}else {
thisEleObj = array;
}
return thisEleObj;
}
To make it more generic, you can override the JSON.stringify function and you won't have to worry about it again, to do this, just paste this at the top of your page:
// Modify JSON.stringify to allow recursive and single-level arrays
(function(){
// Convert array to object
var convArrToObj = function(array){
var thisEleObj = new Object();
if(typeof array == "object"){
for(var i in array){
var thisEle = convArrToObj(array[i]);
thisEleObj[i] = thisEle;
}
}else {
thisEleObj = array;
}
return thisEleObj;
};
var oldJSONStringify = JSON.stringify;
JSON.stringify = function(input){
return oldJSONStringify(convArrToObj(input));
};
})();
And now JSON.stringify will accept arrays or objects! (link to jsFiddle with example)
Edit:
Here's another version that's a tad bit more efficient, although it may or may not be less reliable (not sure -- it depends on if JSON.stringify(array) always returns [], which I don't see much reason why it wouldn't, so this function should be better as it does a little less work when you use JSON.stringify with an object):
(function(){
// Convert array to object
var convArrToObj = function(array){
var thisEleObj = new Object();
if(typeof array == "object"){
for(var i in array){
var thisEle = convArrToObj(array[i]);
thisEleObj[i] = thisEle;
}
}else {
thisEleObj = array;
}
return thisEleObj;
};
var oldJSONStringify = JSON.stringify;
JSON.stringify = function(input){
if(oldJSONStringify(input) == '[]')
return oldJSONStringify(convArrToObj(input));
else
return oldJSONStringify(input);
};
})();
jsFiddle with example here
js Performance test here, via jsPerf

Related

Get object from JSON with jQuery

I'm trying to query a JSON file in my own server using $.getJSON and then cycling inside the objects. No problem so far, then i have an ID which is the name of the object i want to return, but can't seem to get it right:
var id = 301;
var url = "path/to/file.json";
$.getJSON( url, function( json ) {
var items = [];
items = json;
for (var i = 0; i < items.length; i++) {
var item = items[i];
console.log(item);
}
});
This prints the following in the console:
Now let's say i want return only the object == to id so then i can refer to it like item.banos, item.dorms etc.
My first approach was something like
console.log(json.Object.key('301'));
Which didn't work
Any help would be very much appreciated.
It seems like your response is wrapped in an array with one element.
You can access object properties dynamically via square brackets:
var id = 301;
var url = "path/to/file.json";
$.getJSON(url, function(json) {
console.log(json[0][id].banos);
});
As you have the name of the property in the object you want to retrieve you can use bracket notation. you can also simplify your code because of this:
var id = 301;
//$.getJSON("path/to/file.json", function(json) {
// response data from AJAX request:
var json = {
'301': {
banos: 2
},
'302': {
banos: 3
},
'303': {
banos: 4
},
'304': {
banos: 5
},
};
var item = json[id];
console.log(item);
//});
$.each(items,function(n,value){
if(n==301)
alert(value);
});

getting json data from tree and feeding through to associative array

I'm trying to read a JSON API and parse the data into an associative array but I can't seem to get it to work. I must be doing something wrong.
Here is my code:
var matchedValues = {};
$.getJSON(url ,function(data) {
$.each(data, function() {
var value = this["value"];
var climb = this["climb"];
matchedValues[value] = climb;
});
});
console.log(matchedValues); //Outputs Object{}
Any ideas? I don't think I am console logging it correctly or maybe I'm doing something wrong?
Thanks
matchedValues is an Object not an array. try something likmatchedValues['your_key'] to get the value.
I assume that the data coming back from the ajax call is a JSON string, which you wish to parse. If that’s the case, then the problem is already solved using JavaScript’s JSON object:
var matchedValues = {};
$.getJSON(url ,function(data) {
matchedValues=JSON.parse(data);
});
console.log(JSON.stringfy(matchedValues)); //Outputs Object{}
As you see in the above example, you have to reverse the process in order to print it out.
See JSON MDN Article
Try this approach from jquery documentation
EDIT:
$.getJSON(url, function(data) {
var matchedValues = {};
$.each(data, function(key, val) {
items[key] = val;
});
If I understood your question, then your data is an Array of objects, and you want to consolidate them in a big object.
If got it right, then use this approach:
var matchedValues = {};
$.getJSON("ajax/test.json", function(data) {
for (var i = 0; i < data.length; i++) {
for (key in data[i]) {
matchedValues[key] = data[i][key];
}
}
console.log(matchedValues); //this should print your object.
});
The data objects must have different keys or they will be overlapsed.

Use a FOR loop within an AJAX call

So, what i'm trying to do is to send an AJAX request, but as you can see i have many fields in my form, and i use an array to make validations, i would like to use the same array, to pass the values to be sent via AJAX:
I never used the for loop in JS, but seems familiar anyway.
The way the loop is made, obviously wont work:
for (i=0;i<required.length;i++) {
var required[i] = $('#'+required[i]).attr('value');
This will create the variables i want, how to use them?
HOPEFULLY, you guys can help me!!! Thank you very much!
required = ['nome','sobrenome','endereco','codigopostal','localidade','telemovel','email','codigopostal2','localidade2','endereco2','nif','entidade','codigopostal3','localidade3','endereco3','nserie','modelo'];
function ajaxrequest() {
for (i = 0; i < required.length; i++) {
var required[i] = $('#' + required[i]).attr('value');
var dataString = 'nome=' + required[0] + '&sobrenome=' + required[1];
}
$.ajax({
type: "POST",
url: "ajaxload/como.php",
data: dataString,
success: function() {
$(".agendarleft").html("SUCESS");
}
});
To help ensure that the appropriate element IDs and values are passed, loop through the various elements and add the data to an object first.
jQuery:
required = ['nome', 'sobrenome', 'endereco', 'codigopostal', 'localidade', 'telemovel', 'email', 'codigopostal2', 'localidade2', 'endereco2', 'nif', 'entidade', 'codigopostal3', 'localidade3', 'endereco3', 'nserie', 'modelo'];
function ajaxrequest() {
var params = {}; // initialize object
//loop through input array
for (var i=0; i < required.length; i++) {
// set the key/property (input element) for your object
var ele = required[i];
// add the property to the object and set the value
params[ele] = $('#' + ele).val();
}
$.ajax({
type: "POST",
url: "ajaxload/como.php",
data: params,
success: function() {
$(".agendarleft").html("SUCESS");
}
});
}
Demo: http://jsfiddle.net/kPR69/
What would be much cleaner would be to put a class on each of the fields you wish to save and use this to iterate through them. Then you wouldn't need to specify the input names either and you could send a json object directly to the Service;
var obj = {};
$('.save').each(function () {
var key = $(this).attr('id');
var val = $(this).val();
if (typeof (val) == "undefined")
val = "''"
obj[key] = val;
}
Then send obj as the data property of your AJAX call....
There are a few issues with your code. 'required' is being overwritten and is also being re-declared inside of the loop.
I would suggest using pre-written library, a few I included below.
http://jquery.malsup.com/form/#validation
https://github.com/posabsolute/jQuery-Validation-Engine
Otherwise the follow would get you close. You may need to covert the array into a string.
var required = ['nome','sobrenome'];
function ajaxrequest() {
var values;
for (i = 0; i < required.length; i++) {
var values[i] = $('#' + required[i]).attr('value');
}
$.ajax({
type: "POST",
url: "ajaxload/como.php",
data: values,
success: function() {
$(".agendarleft").html("SUCESS");
}
});
}

Is there a Jquery function that can take a #ref id value from a parsed JSON string and point me to the referenced object?

I have been looking for an answer to this all afternoon and i cant seem to find the best way to accomplish what i need to.
My JSON string (returned from a web service) has circular references in it (#ref) which point to $id in the string. Now i know that if use jquery parseJSON it creates the javascript object and i can access properties a la myObject.MyPropertyName. However, when i get to a #ref, i am unsure how to get the object that ID points to (which i assume is already created as a result of the de-serialization...
Should i be iterating though the object and all its child objects until i find it, or is there an easier way?
$.ajax({
type: "POST",
url: "/Task.asmx/GetTask",
data: "{'id':'" + '27' + "'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
_Data = $.parseJSON(msg.d ? msg.d : msg);
_this.Company = _Data[0].t_Program.t_Company;
_this.Program = _Data[0].t_Program;
_this.Task = _Data[0];
},
complete: function () {
}
});
The area in question is _Data[0].t_Program because it does not return an object but rather returns
_Data[0].t_Program
{...}
$ref: "12"
I dont exactly know the best way to get the object with $id "12". Based on the posts below it seems i should loop through the existing object, but i was hoping there was a jquery function that did that...
Many Thanks!
No, jQuery is not natively capable of resolving circular references in objects converted from JSON.
The only library for that which I know is Dojo's dojox.json.ref module.
But, your server application serializes that JSON somehow. Don't tell me that the solution it uses does not offer a deserialisation algorithm!
As my friend Alan, the author of the Xerox Courier (RPC over the net) library, used to say to me, "there are no pointers on the wire."
In other words, it is impossible for a JSON representation of a data structure to be circular. (But a circular structure can be flattened into a non-circular JSON structure.) As the JSON site says:
JSON is built on two structures:
A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.
No pointers!
So the entire JSON will have been turned into Javascript Objects and/or Arrays after the jQuery parseJSON operation completes.
If the original stucture's ref_id values were used as the property names in the JSON / Javascript object, then they'll all be there.
The real issue is that you need to understand how your server serialized its data structure into the JSON data structure. Look in your server-side code to determine that.
Then use Javascript to de-serialize the JSON structure back into the best Javascript structure to fit your needs.
Re: Should i be iterating though the object and all its child objects until i find it, or is there an easier way?
The easier way would be to go through the Javascript structure once, and build up an additional "indexing" object whose properties are the #ref_id and the values are the original structure/value.
Sample:
var jsonCyclicReferenceFixed = JsonRecursive.parse(jsonWithRefAndId);
(function(){
function type(value){
var t = typeof(value);
if( t == "object" && value instanceof Array) {
return "array";
}
if( t == "object" && value && "$id" in value && "$values" in value) {
return "array";
}
return t;
}
function TypeConverterFactory(){
var converters = {};
var defaultConverter = {
fromJson: function(value){ return value; },
toJson: function(value){ return value; },
};
this.create = function(type){
var converter = converters[type];
if(!converter) return defaultConverter;
return converter;
};
this.register = function(type, converter){
converters[type] = converter;
converter.valueConverter = this.valueConverter;
};
}
function ObjectConverter(){
this.fromJson = function(obj){
if( obj == null ) return null;
if( "$ref" in obj ){
var reference = this.dictionary[obj.$ref];
return reference;
}
if("$id" in obj){
this.dictionary[obj.$id] = obj;
delete obj.$id;
}
for(var prop in obj){
obj[prop] = this.valueConverter.convertFromJson(obj[prop]);
}
return obj;
}
this.toJson = function(obj){
var id = 0;
if(~(id = this.dictionary.indexOf(obj))){
return { "$ref" : (id + 1).toString() };
}
var convertedObj = { "$id" : this.dictionary.push(obj).toString() };
for(var prop in obj){
convertedObj[prop] = this.valueConverter.convertToJson(obj[prop]);
}
return convertedObj;
}
}
function ArrayConverter(){
var self = this;
this.fromJson = function(arr){
if( arr == null ) return null;
if("$id" in arr){
var values = arr.$values.map(function(item){
return self.valueConverter.convertFromJson(item);
});
this.dictionary[arr.$id] = values;
delete arr.$id;
return values;
}
return arr;
}
this.toJson = function(arr){
var id = 0;
if(~(id = this.dictionary.indexOf(arr))){
return { "$ref" : (id + 1).toString() };
}
var convertedObj = { "$id" : this.dictionary.push(arr).toString() };
convertedObj.$values = arr.map(function(arrItem){
return self.valueConverter.convertToJson(arrItem);
});
return convertedObj;
}
}
function ValueConverter(){
this.typeConverterFactory = new TypeConverterFactory();
this.typeConverterFactory.valueConverter = this;
this.typeConverterFactory.register("array", new ArrayConverter);
this.typeConverterFactory.register("object", new ObjectConverter);
this.dictionary = {};
this.convertToJson = function(valor){
var converter = this.typeConverterFactory.create(type(valor));
converter.dictionary = this.dictionary;
return converter.toJson(valor);
}
this.convertFromJson = function(valor){
var converter = this.typeConverterFactory.create(type(valor));
converter.dictionary = this.dictionary;
return converter.fromJson(valor);
}
}
function JsonRecursive(){
this.valueConverter = new ValueConverter();
}
JsonRecursive.prototype.convert = function(obj){
this.valueConverter.dictionary = [];
var converted = this.valueConverter.convertToJson(obj);
return converted;
}
JsonRecursive.prototype.parse = function(string){
this.valueConverter.dictionary = {};
var referenced = JSON.parse(string);
return this.valueConverter.convertFromJson(referenced);
}
JsonRecursive.prototype.stringify = function(obj){
var converted = this.convert(obj);
var params = [].slice.call(arguments, 1);
return JSON.stringify.apply(JSON, [converted].concat(params));
}
if(window){
if( window.define ){
//to AMD (require.js)
window.define(function(){
return new JsonRecursive();
});
}else{
//basic exposition
window.jsonRecursive = new JsonRecursive();
}
return;
}
if(global){
// export to node.js
module.exports = new JsonRecursive();
}
}());
Sample:
// a object recursive
// var parent = {};
// var child = {};
// parent.child = child;
// child.parent = parent;
//
//results in this recursive json
var json = '{"$id":"0","name":"Parent","child":{"$id":"1","name":"Child","parent":{"$ref":"0"}}}'
//Parsing a Recursive Json to Object with references
var obj = jsonRecursive.parse(json);
// to see results try console.log( obj );
alert(obj.name);
alert(obj.child.name);

creating a associative array/hash in javascript

I have a form with different groups of checks boxes and trying to pass all the selected values into an array then pass that data into a ajax request.
$('#accessoriesOptions input').each(function(index, value){
if($(this).attr('checked') ){
var newItem =[];
var obj = {};
obj[$(this).attr('value')] = $(this).attr('name'); //I have an hash table with the key-value
wizard.searchArray.push(obj);
}
})
$.ajax({
data : wizard.searchArray
})
I get a wizard.searchArray like :
[0] = {'acc_1' : 'vase'},
[1] = {'acc_3' : 'ceramic'}
I need to create a key-value as I use the key to work out which part of the filtering to use.
The problem
When I do the ajax request, from firebug I see the request as :
/wizard-demo/?undefined=undefined&undefined=undefined
In this case just push add the properties to the obj and use it directly, that's the pair that'll get serialized property when used as the data property, like this:
var obj = {};
$('#accessoriesOptions input').each(function(index, value){
if(this.checked){
obj[this.value] = this.name;
}
})
$.ajax({
data : obj
});
Though this is backwards from a normal <form> submission, if that's what you want it's this instead:
obj[this.name] = this.value;
If you wanted to send the entire form, there's a much shorter/built-in .serialize() method for this:
$.ajax({
data : $("#accessoriesForm").serialize()
});

Categories

Resources