I need to pass an array of objects to a php page as part of a larger data structure. I am trying to replicate this structure in JavaScript and pass it via json.
The arrays keys in php have been set as names which I require later in the process.
I know JavaScript doesn't use associated arrays and arrays in JavaScript are essentially objects but documentation suggests I should be able to use named keys.
If this is the case I should also be able to use variables as named keys by using a different syntax.
Can someone then please show me what I am doing wrong?
Example 1: numeric keys (works)
var dataTargets = [];
var obj = {
'test': 'test'
};
dataTargets["0"] = obj;
alert(JSON.stringify(dataTargets));
Example 2: named keys (fails)
var dataTargets = [];
var obj = {
'test': 'test'
};
dataTargets["test"] = obj;
alert(JSON.stringify(dataTargets));
//outputs []
Example 3: variable keys (fails)
var dataTargets = [];
var dtname = "test";
var obj = {
'test': 'test'
};
dataTargets[dtname] = obj;
alert(JSON.stringify(dataTargets));
//outputs []
The properties are actually being correctly assigned to each array; the problem is that JSON.stringify ignores all non-index properties of arrays (treating them more like lists and less like objects). If you want to use named keys in your objects, you will have to use plain objects {} rather than arrays []:
var alert = console.log.bind(console) // for demo purposes
// Example 1: numeric keys
var dataTargets = {};
var obj = {'test':'test'};
dataTargets["0"] = obj;
alert(JSON.stringify(dataTargets));
// Example 2: named keys
var dataTargets = {};
var obj = {'test':'test'};
dataTargets["test"] = obj;
alert(JSON.stringify(dataTargets));
// Example 3: variable keys
var dataTargets = {};
var dtname = "test";
var obj = {'test':'test'};
dataTargets[dtname] = obj;
alert(JSON.stringify(dataTargets));
//outputs []
what you did actually like this
example1:
var dataTargets = [];
var obj = {'test':'test'};
dataTargets[0] = obj;
alert(JSON.stringify(dataTargets));
// outputs [{test:test}]
what you need is:
var dataTargets = {};
var obj = {'test':'test'};
dataTargets["test"] = obj;
alert(JSON.stringify(dataTargets));
//{"test":{{test:test}}}
because array need to be access by index. And object can be what you need
Related
I am trying to create a javascript object with two array indexes, but it does not seem possible. Why is that? For example:
var arr = ["name","john"];
var obj = {arr[0]:arr[1]}
Computed property names need brackets [myPropName]
var arr = ["name","john"]
var obj = {[arr[0]]:arr[1]}
obj.name // 'john'
You can also do Object.assign,
var arr = ["name","john"];
var obj = {};
var newObj = Object.assign(obj, {[arr[0]]: arr[1]});
console.log(newObj);
If you use arr[0] then js will understand that the property name is arr[0] not "name", so you need [arr[0]] for it to interpret as "name"
var obj = {[arr[0]]:arr[1]}
I must be missing something here, but the following code (Fiddle) returns an empty string:
var test = new Array();
test['a'] = 'test';
test['b'] = 'test b';
var json = JSON.stringify(test);
alert(json);
What is the correct way of JSON'ing this array?
JavaScript arrays are designed to hold data with numeric indexes. You can add named properties to them because an array is a type of object (and this can be useful when you want to store metadata about an array which holds normal, ordered, numerically indexed data), but that isn't what they are designed for.
The JSON array data type cannot have named keys on an array.
When you pass a JavaScript array to JSON.stringify the named properties will be ignored.
If you want named properties, use an Object, not an Array.
const test = {}; // Object
test.a = 'test';
test.b = []; // Array
test.b.push('item');
test.b.push('item2');
test.b.push('item3');
test.b.item4 = "A value"; // Ignored by JSON.stringify
const json = JSON.stringify(test);
console.log(json);
Nice explanation and example above. I found this (JSON.stringify() array bizarreness with Prototype.js) to complete the answer. Some sites implements its own toJSON with JSONFilters, so delete it.
if(window.Prototype) {
delete Object.prototype.toJSON;
delete Array.prototype.toJSON;
delete Hash.prototype.toJSON;
delete String.prototype.toJSON;
}
it works fine and the output of the test:
console.log(json);
Result:
"{"a":"test","b":["item","item2","item3"]}"
I posted a fix for this here
You can use this function to modify JSON.stringify to encode arrays, just post it near the beginning of your script (check the link above for more detail):
// Upgrade for JSON.stringify, updated to allow 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){
if(oldJSONStringify(input) == '[]')
return oldJSONStringify(convArrToObj(input));
else
return oldJSONStringify(input);
};
})();
Another approach is the JSON.stringify() replacer function param. You can pass a 2nd arg to JSON.stringify() that has special handling for empty arrays as shown below.
const arr = new Array();
arr.answer = 42;
// {"hello":"world","arr":{"answer":42}}
JSON.stringify({ hello: 'world', arr }, function replacer(key, value) {
if (Array.isArray(value) && value.length === 0) {
return { ...value }; // Converts empty array with string properties into a POJO
}
return value;
});
Alternatively you can use like this
var test = new Array();
test[0]={};
test[0]['a'] = 'test';
test[1]={};
test[1]['b'] = 'test b';
var json = JSON.stringify(test);
alert(json);
Like this you JSON-ing a array.
Json has to have key-value pairs. Tho you can still have an array as the value part. Thus add a "key" of your chousing:
var json = JSON.stringify({whatver: test});
My for loop looks like this,
var myObj = data.response.carTypes;
for (var key in myObj) {
if (myObj.hasOwnProperty(key)) {
console.log(myObj[key]);
}}
output on console looks like this,
car1
car2
car3
i want to convert this data something like this,
$scope.myArray = [{"cars":car1}, {"cars":car2}, {"cars":car3}]
how can I convert it this way in javascript?
You can use var json = JSON.stringify(jsObject) and var jsObject = JSON.parse("json string")
Just iterate over object and push it into array:
var myObj = data.response.carTypes;
var myArr = [];
for (var key in myObj) {
if (myObj.hasOwnProperty(key)) {
myArr.push(myObj[key]);
}
}
console.log(myArr);
You can convert the array to JSON using var myJsonArray = JSON.stringify(myArray).
If you're doing this conversion in an older browser, you can use a script.
In order to get your array from the JSON you created, you can use:
var myArray = JSON.parse(myJsonArray)
Also, bear in mind that when you use the same key for several objects in your JSON, the last key with the same name is the one that is going to be used.
Here you have to use javascript object.
say
$scope.myArray = [];
var carlist.cars="";
var carlist={};
carlist is a object which cars is a property
then you can try this way:
var myObj = data.response.carTypes;
for (var key in myObj) {
if (myObj.hasOwnProperty(key)) {
carlist.cars=myObj[key];
myArray.push(carlist);
console.log(myArray);
}}
You just need to create a new array and push a new object to it in each iteration:
$scope.myArray = [];
for (var key in myObj) {
if (myObj.hasOwnProperty(key)) {
$scope.myArray.push({cars:myObj[key]});
}
};
Demo:
var myObj = {
a: "Car1",
b: "Car2",
c: "Car3"
};
var carsArray = [];
for (var key in myObj) {
if (myObj.hasOwnProperty(key)) {
carsArray.push({cars:myObj[key]});
}
};
console.log(carsArray);
Below is my JS code :
var checkedLength = $(ele).parent().parent().find('table').find(':checkbox:checked').length;
if(checkedLength)
{
$(ele).parent().parent().find('table').find(':checkbox:checked').each(function(i) {
$(this).parent().removeClass().addClass('play');
$(this).prop('checked',false);
var agn = $(this).data('agn');
var value = $(this).data('kid');
checkedValues[agn] = {};
// Make bar an array, if it's not defined yet
checkedValues[agn]["bar"] = checkedValues[agn]["bar"] || [];
checkedValues[agn]["bar"].push(value);
});
console.log(checkedValues);
}
From above code am getting output as :
object {agnName => bar[0] = 6}
Desired O/P :
object {agnName => bar[0] = 4,bar[1] = 5 , bar[2]=> 6}
Can anyone guide me how can achieve this array structure ??
Thanks.
You have a test to see if checkedValues[agn] exists and you create it as an empty object if it doesn't. However you then immediately try to push to an array within that object that doesn't exist
Try changing
checkedValues[agn] = {};
checkedValues[agn]['pl'].push = $(this).data('kid');
To
checkedValues[agn] = {pl:[]};/* add property "pl" who's value is empty array*/
/* now the array exists , can push elements into it*/
checkedValues[agn]['pl'].push($(this).data('kid'));
Also note push() syntax you are using is incorrect.....should be push( value )
You want an object, not an array:
checkedValues = {};
checkedValues.foo = {};
checkedValues.foo.bar = 'baz';
// Another way:
checkedValues["keyname"] = "value";
// You can also use variables as keys
var agn = "foo";
checkedValues[agn] = "value";
// Just don't forget to init nested objects
var agn = "foo";
checkedValues[agn] = {};
checkedValues[agn]["bar"] = "value";
// If you need an array inside:
var agn = "foo";
checkedValues[agn] = {};
// Make bar an array, if it's not defined yet
checkedValues[agn]["bar"] = checkedValues[agn]["bar"] || [];
checkedValues[agn]["bar"].push("value");
associative arrays are done as objects in Javascript:
var data = {
agnName: {
pl: [4, 5, 6]
}
}
so you can access data.agnName.pl[0] to return 4 or more dynamically with data['agnName'].pl[0]
To create a mulch-dimensional obj. you have to initialize obj and then you can enter value. like below
var obj = {}
obj[dynamicval1] = {};
obj[dynamicval1][dynamicval2] = {};
obj[dynamicval1][dynamicval2] = {key1:value1,key2:value2};
Hope it works!
If I create a JavaScript object like:
var lst = [];
var row = [];
row.Col1 = 'val1';
row.Col2 = 'val2';
lst.push(row);
And then convert it to a string:
JSON.stringify(lst);
The result is an object containing an empty object:
[[]]
I would expect it to serialize like:
[[Col1 : 'val1', Col2: 'val2']]
Why do the inner objects properties not serialize?
Code snippet at JSFiddle.
Because row is an array, not an object. Change it to:
var row = {};
This creates an object literal. Your code will then result in an array of objects (containing a single object):
[{"Col1":"val1","Col2":"val2"}]
Update
To see what really happens, you can look at json2.js on GitHub. This is a (heavily reduced) snippet from the str function (called by JSON.stringify):
if (Object.prototype.toString.apply(value) === '[object Array]') {
//...
length = value.length;
for (i = 0; i < length; i += 1) {
partial[i] = str(i, value) || 'null';
}
//...
}
//...
for (k in value) {
if (Object.prototype.hasOwnProperty.call(value, k)) {
//...
}
//...
}
//...
Notice that arrays are iterated over with a normal for loop, which only enumerates the array elements. Objects are iterated with a for...in loop, with a hasOwnProperty test to make sure the proeprty actually belongs to this object.
You use your inner array like an object, so make it an object instead of an array.
var lst = [];
var row = {};
row.Col1 = 'val1';
row.Col2 = 'val2';
lst.push(row);
or use it as an array
var lst = [];
var row = {};
row.push( 'val1' );
row.push( 'val2' );
lst.push(row);
You want row to be a dictionary, not a vector. Define it like this:
var row = {};
Since an array is a datatype in JSON, actual instances of Array are stringified differently than other object types.
If a JavaScript Array instance got stringified with its non-numeric keys intact, it couldn't be represented by the [ ... ] JSON array syntax.
For instance, [ "Col1": "val1"] would be invalid, because JSON arrays can't have explicit keys.
{"Col1": "val1"} would be valid - but it's not an array.
And you certainly can't mix'n'match and get { "Col1": "val1", 1, 2, 3 ] or something.
By the way, this works fine:
var lst = [];
var row = {};
row.Col1 = 'val1';
row.Col2 = 'val2';
lst.push(row);
alert(JSON.stringify(lst));