Parsing a JSON string to array, not object - php

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.

Related

How extract value from a json object using javascript

Following is my json object produced using php script
$to_encode[]= mysql_fetch_assoc($result);
echo json_encode($to_encode);
and the output is
[{"wid":"2","repid":"1"}]
to extract values of wid and repid I used below given code in js
var obj = JSON.parse(data);
var a = obj.["wid"];
var b = obj.["repid"];
but I'm getting value for a and b as undefined instead of 2,1
Looks like your JSON encodes not simply one object, but an array containing one object. But that array doesn't have the wid and repid properties, only the object inside the array has!
Try
{"wid":"2","repid":"1"} to encode just an object without putting it into an array or
obj[0]["wid"] to access the properties of the first (and only) object in the array.
By the way, if you know the names of the properties, you should use dot notation: obj[0].wid instead of obj[0]["wid"].
Your json object is actually an array of objects (in this case there only is one object: {"wid":"2","repid":"1"}).
This should work
var obj = data[0] //access the first element of the json array
var a = obj.wid;
var b = obj.repid;
Try using obj[wid]. Array have wid as key and 2 as a value.

merge values of unique keys of json string

i have a json output code like this:
{"a":{"p1":"1"},"a":{"p2":"2"},"b":{"b1":"b2"}}
how to convert it to below using javascript or jquery or php ?
{"a":{"p1":"1","p2":"2"},"b":{"b1":"b2"}}
EDIT:
i generate json code by this code:
parts2.push('"'+$(this).attr('alt')+'":{"'+$(this).attr('title') + '"' + ":" + '"'+$(this).attr('value') + '"}' );
however $(this).attr('alt') maybe repeated in loop and i want to prevent duplicate key and instead append value to that key
Each property of an object is supposed to have a unique key name. If you try to parse JSON with duplicate key names, only the last occurring value is used, so it isn't possible to parse this with the native JSON.parse and still expect data to be preserved.
As per your edit, you can prevent the duplicates from ever occurring:
var obj = {};
if typeof obj[$(this).attr('alt')] == "undefined"
obj[$(this).attr('alt')] = {};
obj[$(this).attr('alt')][$(this).attr('title')] = $(this).attr('value');
parts2.push(JSON.stringify(obj));
You should merge the value before you generate the JSON string or you have to implement a JSON parser yourself to parse your JSON.
In http://www.ietf.org/rfc/rfc4627.txt?number=4627:
The names within an object SHOULD be unique
Instead of stringing the pseudo-JSON, just create an object, fill that, and stringify the object when you send it:
var parts = {};
$('.foo')each(function()
{//the loop, here parts is being filled
parts.[$(this).attr('alt')] = parts.[$(this).attr('alt')] || {};//initialize to object if property doesn't exist
parts.[$(this).attr('alt')] = [$(this).attr('title')] = $(this).attr('value');
});
//make JSON:
partsJSON = JSON.stringify(parts);
//{a:{p1:foo,p2:bar},b:{p3:foobar}} or something

Convert JSON to multidimensional JavaScript array

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);

Pass string to json with jquery and loop the elements

Hello there I have a really complex php script that produces a javascript file in jquery
There is a string that is stored in an input type text and I want to converted into json.
The input type text has undedined number of elements.
So I initisialize the string in the input box
<input type="text" id="selectbuttons" value="{}">
After some actions the string in the input box is something like that:
{"button":"bt1","style":"style1"},{"button":"bt2","style":"style2"}
etc...
Then this is my script , i use the function addScriptto to add it to the document's header, also I am using the core of jquery jquery-1.6.2.min.js to make the json object
$document->addScriptto('
$.noConflict();
jQuery(document).ready(function($) {
var loaded=$("#selectButtons").val();
var obj = jQuery.parseJSON(loaded);
}); //end of dom ready
');
But I can't make it work, when the string is not empty
Is there something wrong with my json syntax? Also, I would be later able to loop all the elements and retrieve the data? Thanks in advance
Your JSON string should be in an array format like below
[{"button":"bt1","style":"style1"},{"button":"bt2","style":"style2"}]
And then you can use the $.each to loop through the JOSN values as below:
$.each(yourJSONstring,function(i,values) {
//yourJSONstring holds the JSON array
// i is just the loop index. it will increment by 1 in every loop
alert(values.button) //will alert bt1 in the 1st loop, bt2 in 2nd
alert(values.style) //will alert style1 in 1st loop, style2 in 2nd
//You can have values here of the keys in JSON using the dot notation as above and do your operations.
})
maybe just put [ ... ] around the JSON so it is understood as an array, something like:
var obj = jQuery.parseJSON( '[' + loaded + ']' );
Yes, your JSON syntax is wrong. You should have it like:
[{"button":"bt1","style":"style1"},{"button":"bt2","style":"style2"}]
and then you will have array of your objects.

Sending array from javascript to php not working correctly

I'm creating an array on the jquery side this way. The array is an array of arrays where each element is an array that looks like [jskey, jsvalue].
var jsarray = [];
// jsarray.push([jskey, jsvalue]);
jsarray.push([1, 123]);
jsarray.push([2, 98]);
jsarray.push([3, 107]);
jsarray.push([4, 34]);
I then add the array to an element of a form before it's submitted
$('#myform input[name=jsvalues]').val(jsarray);
On the php side, I'm expecting to receive an array of array, but all I get when I do a print_r() or var_dump() is a string that looks like this
string() "1,123,2,98,3,107,4,34"
Attribute values are strings. When you convert an array to a string, you get each element in that array converted to a string and separated by commas (unless you override the toString() method (hint: don't)).
I suggest converting the array to JSON and then assigning that to the form control. You can then parse the JSON in PHP.
http://json.org has links (at the bottom) to PHP and JS implementations of JSON serializers / deserializers.
David Dorward gave a really good solution.
To clarify a little bit, when you assign a complex object (like an array) to the attribute of a HTML element (that's what jQuery does when you call val()), the object is converted into a string (by calling the toString method on the object).
An array has a toString method that does exactly what you are experiencing: a list of the values inside the array separated by commas:
[1, [2, 3]].toString(); // returns "1,2,3"
To transmit complex objets, you can use JSON (JavaScript Object Notation) which is native in JS:
$('#myform input[name=jsvalues]').val(JSON.stringify(jsarray));
On the server side, PHP 5 has a really fast JSON API:
$jsvalues = json_decode($_POST['jsvalues']);
You could convert that string back into an array of arrays, assuming they were all pairs:
$arr = explode(",", $_POST['jsvalues']);
$jsvalues = array();
for ($i = 0; $i < count($arr); $i += 2) {
$jsvalues[] = array($arr[$i], $arr[$i + 1]);
}

Categories