I have a PHP array that has a table id as the key and a table field as the value.
Example PHP:
while($row = mysql_fetch_array($result))
{
$id = $row['id'];
$array[$id] = $row['some_field'];
}
I then use json_encode($array) to get something like:
{"id1":"value1","abc":"123","xyz":"789"}
How can I loop through this in jQuery? From what I have found so far it seems like I need to know the key. So:
var obj = jQuery.parseJSON(jsonVar);
alert(obj.abc); //prints 123
But how can I get these values if I don't know the keys since they are dynamic?
Do I need to restructure my PHP array?
Once you encode an associative array in php into a JSON object it is no longer an array, it is an object with keys and values. You can iterate through them in javascript using for..in
for (var key in obj) {
console.log(obj[key]);
}
Note: for..in does not garuntee order, if you need to ensure order you will have to make your array indexed, instead of key=>value, and use a for loop (or while) instead.
You can get the keys of your array using Object.keys, then loop through them. Unlike for...in, this gives you the option to .sort() the keys before processing them:
var keys = Object.keys(obj).sort(); // sorting is optional
for (var i=0; i<keys.length; i++) {
var key = keys[i],
val = obj[key];
console.log(key+":"+val);
};
In older browsers, you'll need a polyfill to enable the Object.keys method. MDN has one on their documentation page.
Related
I have a php array that I assigned to a javascript variable with json_encode. The php array is numerical not associative.
Example: simpleArray[5][7]=1.50. I need to be able to access the 1.50 after the array has been json_encoded based on the index values.
PHP:
$simpleArray= [];
foreach($childProducts as $child) { //cycle through simple products to find applicable
$simpleArray[$child->getVendor()][$child->getColor()] = $child->getPrice();
var_dump ($simpleArray);
}
Javascript:
var simpleArray = <?=json_encode($simpleArray)?>;
//..lots of unrelated code
for(var i=0; i < IDs.length; i++)
{
console.log(simpleArray);//see the picture of me below
var colorSelected = $j("#attribute92 option:selected").val(); //integer value
$j('.details'+data[i].vendor_id).append('<li class="priceBlock">$'+simpleArray[i][colorSelected]+'</li>');
}
Console.log(simpleArray):
Here you are likely trying to access values that don't exist in your object:
simpleArray[i][colorSelected]
Based on your for loop definition, you can have i values of 0, 1, 2 which don't exist in the object shown (which has properties at keys: 3,4,5). Also your for loop has no relation at all to the number of items in your object, which I am not sure is intended.
Also, colorSelected derives it's value from a call to val() which returns a string you you probably want to change the line where it is defined to:
var colorSelected = parseInt($j("#attribute92 option:selected").val());
This will make it an integer value.
Problem: returns array, but not in json.
Result: must return array with in array. outer array has key with numbers and value is array with keys "ID" and "NAME" and there values are assigned from database.
$i = 0;
$json_values = array();
while($sctg = mysql_fetch_assoc($get_sctg)){
$json_values[$i] = array("ID" => $sctg['ID'], "NAME" => $sctg['NAME']);
$i++;
}
echo json_encode($json_values);
Your code is perfectly fine - you just misunderstood the different between arrays and objects in JavaScript.
[{"ID":"4","NAME":"asdasd"},
{"ID":"3","NAME":"LOKS"},
{"ID":"1","NAME":"LOL"}]
This is JSON containing an array with three elements. Each element is an object with the properties ID and NAME.
Let's assume that array is stored in data. You can iterate over the objects in that array with a simple for loop:
for(var i = 0; i < data.length; i++) {
var row = data[i];
// Here you can use row.ID and row.NAME
}
I guess you expected your JSON to look like this:
{
0: {"ID":"4","NAME":"asdasd"},
1: {"ID":"3","NAME":"LOKS"},
2: {"ID":"1","NAME":"LOL"}
}
This would actually be bad since objects in JavaScript are not ordered (even though they actually are in most browsers, but that's not guaranteed!). So when iterating over the rows in such an element (using for(var key in data)), you would not necessarily get the row with ID=4 first just because its key is zero.
However, if you really want an object instead of an array for some reason (you don't!), you could always cast the array to object:
echo json_encode((object)$json_values);
As a side-note, usually it's a good idea to have an object as the top-level element in JSON for security reasons (you can redefine the array constructor and then include something with a top-level array with a script tag and thus access data usually protected by the same origin policy if it was accessed by an XHR request), so I'd change the PHP code like this:
echo json_encode(array('rows' => $json_values));
No need to use $i++; directly use
while($sctg = mysql_fetch_assoc($get_sctg)){
$json_values[] = array("ID" => $sctg['ID'], "NAME" => $sctg['NAME']);
}
and it will return you the JSON
I receive from the server a JSON like the following:
{"0":{"0":"image1.jpg","1":"texthere","2":"0"},"1":{"0":"image66.jpg","1":"texthere","2":"1"},"2":{"0":"image12.jpg","1":"texthere","2":"2"},"3":{"0":"image44.jpg","1":"texthere","2":"3"},"4":{"0":"image34.jpg","1":"texthere","2":"4"},"5":{"0":"image33.jpg","1":"texthere","2":"5"},"6":{"0":"image21.jpg","1":"texthere","2":"6"},"7":{"0":"image32.jpg","1":"texthere","2":"7"},"8":{"0":"image13.jpg","1":"texthere","2":"8"},"9":{"0":"image11.jpg","1":"texthere","2":"9"},"10":{"0":"image03.jpg","1":"texthere","2":"10"},"length":"12"}
The developer who coded this used JSON_FORCE_OBJECT as a parameter of the json_encode method in PHP.
In JavaScript is there any "magics" (that is, not a custom function) to convert this structure to a multidimensional array?
I would want something like:
[["image1.jpg","texthere","2"],["image66.jpg","texthere","1"]]...
Disclaimers:
- I'm looking for a native implementation (not JQuery);
- The PHP can be eventually changed (if needed);
Any help is appreciated, thanks in advance.
The easiest way I can think of to do what you want is to use regular expressions to convert the JSON from object literals to array literals.
Unfortunately, Simon Cowell is more magical than this approach.
//I don't know why you don't want a custom function.
function dataToArray(data)
{
data = data.replace(/"[0-9]+":/g,""); //Remove all index keys
data = data.replace(/,"length":"[0-9]+"/g,""); //Remove length key-value pair
data = data.replace(/{/g,"["); //Change the left brackets
data = data.replace(/}/g,"]"); //Change the right brackets
return JSON.parse(data);
}
Not magic, but you can loop over the data and test what type of value it has.
A basic example would be as follows. It doesn't have the error checking I'd want in production code though.
var data = {"0":{"0":"image1.jpg","1":"texthere","2":"0"},"1":{"0":"image66.jpg","1":"texthere","2":"1"},"2":{"0":"image12.jpg","1":"texthere","2":"2"},"3":{"0":"image44.jpg","1":"texthere","2":"3"},"4":{"0":"image34.jpg","1":"texthere","2":"4"},"5":{"0":"image33.jpg","1":"texthere","2":"5"},"6":{"0":"image21.jpg","1":"texthere","2":"6"},"7":{"0":"image32.jpg","1":"texthere","2":"7"},"8":{"0":"image13.jpg","1":"texthere","2":"8"},"9":{"0":"image11.jpg","1":"texthere","2":"9"},"10":{"0":"image03.jpg","1":"texthere","2":"10"},"length":"12"};
function data_to_array(data) {
var array = [];
for (var key in data) {
var value = data[key];
if (typeof value === 'string') {
array[key] = value;
} else {
array[key] = data_to_array(value);
}
}
return array;
}
var array = data_to_array(data);
console.log(array);
Make sure you add hasOwnProperty checks if your object prototypes might be messed with. You should probably also add a check to make sure that only integer keys are added to the array.
There is no built-in functions. If you have JSON string, you can do string replacement, otherwise you have to loop as shown below.
var dataObject = {"0":{"0":"image1.jpg","1":"texthere","2":"0"},"1":{"0":"image66.jpg","1":"texthere","2":"1"},"2":{"0":"image12.jpg","1":"texthere","2":"2"},"3":{"0":"image44.jpg","1":"texthere","2":"3"},"4":{"0":"image34.jpg","1":"texthere","2":"4"},"5":{"0":"image33.jpg","1":"texthere","2":"5"},"6":{"0":"image21.jpg","1":"texthere","2":"6"},"7":{"0":"image32.jpg","1":"texthere","2":"7"},"8":{"0":"image13.jpg","1":"texthere","2":"8"},"9":{"0":"image11.jpg","1":"texthere","2":"9"},"10":{"0":"image03.jpg","1":"texthere","2":"10"},"length":"12"};
function getArray(object){
var array = [];
for(var key in object){
var item = object[key];
array[parseInt(key)] = (typeof(item) == "object")?getArray(item):item;
}
return array;
}
var dataArray = getArray(dataObject);
I've got a PHP array and echo that into javascript with json encode, i need to do it this way because it's going to be very dynamic. This is the code it echo's:
{"notempty":true}
And i use this to, convert it to javascript:
var myarray = eval('(' + json + ')');
For some reason it creates an object instead of an array and for that reason i cant use .length or a for loop.
Does someone know what im doing wrong here?
Thanks
You're trying to treat an Object like an Array, and an Object is not an Array, it is an Object.
Any time you see {} in JSON, that means "What is contained within these hallowed brackets is a dynamic object". When you see [], that means "Behold! I am an Array" (there are notable exceptions to this one: jQuery does some special work with to make itself look like an array).
So, in order to iterate through an Object, you'll want to use for... in.
// eval BAD unless you know your input has been sanitized!.
var myObj = JSON.parse('{"notempty":true}');
// personally, I use it in for... in loops. It clarifies that this is a string
// you may want to use hasOwnProperty here as sometimes other "keys" are inserted
for( var it in myObj ) console.log( "myObj["+it+"] = " + myObj[it] );
{} is an object, which contains one attribute named notempty. If you want an array, it'd have to be
[{"notempty":true}]
which is an array with a single element at index 0, which is an object with the single attribute 'notempty';.
By default, if you use encode an assoc array in php, it will become a js object when you decode. In order to have it be an array, you need to make it an array in php:
PHP:
$arr = "['notempty','notempty2','notempty3']";
Otherwise, you should convert it to an array in JS, but that seems to me a waste since looping through the object in javascript is so much easier:
Javascript:
var arr = new Array();
for(var i in obj) arr[i] = obj[i];
You can use jQuery to parse it into an array like this:
var p = [];
$.each(jsonData, function (key, val) {
p.push([val.propertyOne, val.propertyTwo]);
});
I am presuming of course that you want to parse JSON, not an array or any other string.
I'm trying to dynamically build a javascript array where _tags is a globally defined array and then send it to php via ajax request. Basically I need the uid as a key and x,y as a sub array. in php it would look something like
$arr[$uid] = array('x'=>$x,'y'=>$y);
but im having trouble figuring out an array like this in javascript, heres what i have
function add_tag_queue(uid,x,y){
var arr = new Array(3);
arr[0] = uid;
arr[1] = x;
arr[2] = y;
_tags.push(arr);
}
This works ok as long as their is only
one entry being added to the array,
I'm adding multiple values, in other
words the function will run a few
times and then i want to send that
entire array, but this seems to just
be adding everything with a comma
delimeter.
Im not sure what youre saying exactly here. The second example i previously gave assumes there is a single x,y pair for each uid but places no limits on how many uids are in _tags. Thats why var _tags = {}; is ourside of the function - so its a global variable.
The following modifications would allow you to have multiple x,y pairs for each uid:
function add_tag_queue(uid,x,y){
/*
* detect if _tags[uid] already exists with one or more values
* we assume if its not undefined then the value is an array...
* this is similar to doing isset($_tags[$uid]) in php
*/
if(typeof _tags[uid] == 'undefined'){
/*
* use an array literal by enclosing the value in [],
* this makes _tags[uid] and array with eah element of
* that array being a hash with an x and y value
*/
_tags[uid] = [{'x':x,'y':y}];
} else {
// if _tags[uid] is already defined push the new x,y onto it
_tags[uid].push({'x':x, 'y':y});
}
}
This should work:
function add_tag_queue(uid,x,y){
_tags.push([uid, x,y]);
}
if you want the uid as the key then you need to use an object/hash not an array
var _tags = {}; // tags is an object
function add_tag_queue(uid,x,y){
_tags[uid] = {'x':x,'y':y};
}
You could always just build it in php and json_encode it.
You're looking to implement an associative array in Javascript. While Javascript does not support associative arrays, Javascript objects can be treated much the same.
Try this instead:
_tags = {}
function add_tag_queue(uid,x,y){
_tags[uid] = {x:x, y:y};
}
_tags is now an object and you'll be adding a new object at the uid key. Likewise, the x,y pair is stored in an object. The first x is the key and the second is the value. To clarify, you could write it like this:
function add_tag_queue(uid,xValue,yValue){
_tags[uid] = {x:xValue, y:yValue};
}
It looks very similar to the PHP example you gave:
function add_tag_queue(uid,x,y){
_tags[uid] = {x: x, y: y};
}
This is how I create multidimensional arrays in JS. I hope this helps.
var arr= [];
arr[uid] = new Array();
arr[uid]["x"] = xvalue;
arr[uid]["y"] = yvalue;