Parsing JSON array of arrays in jQuery - php

I'm currently using jQuery's $.get() to process IDs entered in a text field with a database. It currently works quite well, especially the PHP which can handle multiple comma-separated entries.
The issue I'm having is with jQuery; more specifically, JSON parsing. The PHP file returns an array of arrays, which is used to manipulate a <table>. While it works with single entries, i.e. "12346", it doesn't work with multiple entries, such as "123456,789101".
The error is specifically thrown at Line 77: var serverData = $.parseJSON(data)[0];
Here's the stack trace
Uncaught SyntaxError: Unexpected token s in JSON at position 2
at Function.parse [as parseJSON] (<anonymous>)
at Object.<anonymous> (myScript.js:77)
at u (jquery.min.js:2)
at Object.fireWith [as resolveWith] (jquery.min.js:2)
at k (jquery.min.js:2)
at XMLHttpRequest.<anonymous> (jquery.min.js:2)
Here is what my code looks like so far:
PHP:
$sql = "SELECT * FROM students";
$stmt = $pdo->prepare($sql);
$stmt->execute();
//Database access is arbitrary
while ($row = $stmt->fetch()) { //iterate through db results
$student_array[$row['sid']] = array(
'name' => $row['name'],
'advisory' => $row['advisory']
);
}
$json_params[] = array(
"students" => $student_array, /* The array of arrays */
"success" => "n students were checked in, nice!" /* generic message */
"failure" => "m students couldn't be accessed"
);
echo json_encode($json_params);
jQuery:
$.get("check-in.php", {value: inputValue}).done(function(data) {
var serverData = $.parseJSON(data)[0];
if (serverData.success) {
$.each(serverData.students, function(sid, tableValues) {
/* Create a <tr> based on the information (using the key as the SID,
* name, and advisory, and insert that <tr> into a table */
});
}
}
This might be the culprit, which is the JSON text causing the issue:
[{
"students": {
"245680":{"name":"John Doe","advisory":"9"},
"135791":{"name":"Jane Smith","advisory":"7"}
},
"success":"2 students were checked in!"
}]
I'm quite puzzled as it's been working fine with single number entries. I've looked at solutions to "parsing JSON arrays of arrays" on this site, but I've tried all the suggestions for those. Any help is greatly appreciated!

I don't see the need to make $json_params as an array. It is stored outside of looping and executed only once. Just remove [] part. THe code will look like this.
$json_params = array(
"students" => $student_array, /* The array of arrays */
"success" => "n students were checked in, nice!" /* generic message */
"failure" => "m students couldn't be accessed"
);
In your jQuery, you can simply retrieve JSON result without having to access key array. [0] isn't necessary as [] in $json_params is removed.
var serverData = $.parseJSON(data);

Your code has this:
var serverData = $.parseJSON(data)[0];
but it's failing because data is already an object (not a json string that needs to be parsed).
Try this:
var serverData = data[0];

Related

Read POST data in AJAX call

I have some Session values that I am constantly changing via Ajax calls. I can't seem to get a handle on the POST data to process it and set the values.
What I am passing to it here is an array of strings like is shown in my code below.
Here is where AJAX calls:
var sessionValues = [];
str = {"PID": "1", "Level": "Main", "MenuName": "Kitchen", "State": "CHECKED"}
sessionValues.push(str);
var postObj = {"sessionData": sessionValues};
$.ajax({
type: 'POST',
data: {'data': postObj},
url: 'setSession.asp'
}).done(function(response){
console.log(response);
})
I have this working fine in a PHP version of the program but my ASP version is not grabbing the data. Here is my PHP ver and the ASP ver as best as I could convert it.
<-- php setSession.php works fine -->
$data = $_POST['data'];
foreach ($data['sessionData'] as $key => $value) {
$projectProduct = "1";
$level = $value["Level"];
$menuName = $value["MenuName"];
$state = $value["State"];
$_SESSION['PID:'.$projectProduct][$level][$menuName]['menu_state'] = $state;
echo "[PID:".$projectProduct."][".$level."][".$menuName."][".$state."]<br>";
}
0 =>>>>> Array<br>[PID:1][Main][Kitchen][CHECKED]
Here I want to do the same thing in ASP
' setSession.asp
data = Request.Form("data")
For Each part In data("sessionData")
projectProduct = part("PID")
level = part("Level")
menuName = part("MenuName")
state = part("State")
Session("PID:" & projectProduct).Item(level).Item(menuName).Remove("menu_state")
Session("PID:" & projectProduct).Item(level).Item(menuName).Add "menu_state", state
response.write("[PID:" & projectProduct&"]["&level&"]["&menuName&"]["&state&"]<br>")
Next
outputs blank
It looks like it never has any data but doesn't throw any errors. Am I reading the POST object correctly?
[edit]
Here is the RAW POST data captured from Fiddler:
data%5BsessionData%5D%5B0%5D%5BPID%5D=1&data%5BsessionData%5D%5B0%5D%5BLevel%5D=Main&data%5BsessionData%5D%5B0%5D%5BMenuName%5D=Kitchen&data%5BsessionData%5D%5B0%5D%5BState%5D=CHECKED
here I used a URL Decode on that string-
data[sessionData][0][PID]=1&data[sessionData][0][Level]=Main Level Plan&data[sessionData][0][MenuName]=Kitchen&data[sessionData][0][State]=CHECKED
This looks like I should be able to loop through the strings now by using
For Each part In Request.Form("data[sessionData]")
but nothing happens. I added a simple loop to look at the request.form and here is what it is seeing:
for each x in Request.Form
Response.Write(x)
Next
' outputs -> data[sessionData][0][PID]data[sessionData][0][Level]data[sessionData][0][MenuName]data[sessionData][0][State]
I guess what this comes down to is just reading through and processing that string correctly, or multiple if more than one is sent. Correct?
The RAW output definitely helps work out what is going on.
What is happening is jQuery is translating the JSON structure into HTTP POST parameters but during the process, it creates some overly complex key names.
If you break down the key value pairs you have something like
data[sessionData][0][PID]=1
data[sessionData][0][Level]=Main Level Plan
data[sessionData][0][MenuName]=Kitchen
data[sessionData][0][State]=CHECKED
As far as Classic ASP is concerned the this is just a collection of string key and value pairs and nothing more.
The correct approach to work out what these keys are is to do what you have done in the question, but with some minor alternations.
For Each x In Request.Form
Response.Write(x) & "=" & Request.Form(x) & "<br />"
Next
Which when outputted as HTML will look similar to the break down shown above.
Armed with the knowledge of what the keys are you should be able to reference them directly from the Request.Form() collection.
Dim pid: pid = Request.Form("data[sessionData][0][PID]")
Response.Write pid
Output:
1

Multiple JSON data

I checked every stack overflow solution for it. On ajax request PHP return JSON data but it has multiple JSON data.
var json = '[{"key":"amazon"},{"key":"a a"},{"key":"a and w"},{"key":"a aa"},{"key":"a and e"},{"key":"a aa movie"},{"key":"a aa songs"},{"key":"a aa telugu movie"},{"key":"a aa full movie"},{"key":"a and f"}][{"key":"a beautiful mind"},{"key":"a boogie"},{"key":"a bigger splash"},{"key":"a bronx tale"},{"key":"a brief history of time"},{"key":"a bola"},{"key":"a bugs life"},{"key":"a bientot"},{"key":"a bathing ape"},{"key":"a beautiful mess"}]';
console.log(JSON.parse(json));
$.each(JSON.parse(json), function(idx, obj) {
console.log(obj.key);
});
in var JSON there are two sets one [] and second [] which is causing problems to iterate. If it has only one set [] then it works fine.
PHP Code:
foreach($str as $key => $keyword){
$finalData[$key]['key'] = $keyword;
}
print_r(json_encode($finalData));
Note: It may return data with more than 100 of [], but in above example I just mention two.
Kindly help me out.
What you are trying to create is invalid JSON.
Please wrap your two [] with another [] and comma between both []. Refer code below.
//Sample Code and data
var json = '[[{"key":"amazon"},{"key1":"amazon1"}],[{"key":"amazon"},{"key1":"amazon1"}]]';
console.log(JSON.parse(json));
If more help needed, I'm happy to help.
Thanx, Happy Coding.

How to: Properly use PHP to encode data into JSON format, and request the data with jquery/ajax

I am trying to create an address book of sorts.
I can successfully connect to the database and insert data with a php script.
I have even managed to display json encoded data of my table rows, though I don't know if I am doing it right.
What I am actually trying to accomplish:
I would like to be able to make an ajax request for say, and ID, then get back all of that ID's corresponding data, (wrapped in Json - At least I think it needs to be..).
With the ajax script, I would like to be able to save the returned corresponding data to an input field in an html file.
I would also like to know if it would be better to try to return HTML to the ajax call, and input the data into the html input fields that way?
So far I am having limited success, but here is what I have so far...
I have a DB connection script:
$host = "localhost";
$user = "user";
$pass = "pass";
$db = "data_base";
$mysqli = new mysqli($host, $user, $pass, $db);
if($mysqli->connect_error)
die('Connect Error (' . mysqli_connect_errno() . ') '. mysqli_connect_error());
return $mysqli;
A mysql ISAM DB with the following columns:
id, user, pass, nickname, address, facebook, twitter, linkedin, youtube
ID should be unique
User is an index
Pass is an index
nickname is an index
address is primary - though its possible that id should be...
Facebook, Twitter, Linkedin, and Youtube are all indexes.
Note: I would be happy to change index, primary, etc as somebody sees fit...
EDITED!**Now my query page:
error_reporting(E_ALL); ini_set("display_errors", 1);
include 'db/dbcon.php';
//Start connection with SQL
$q = "SELECT * FROM `cfaddrbook` WHERE key = '111111'";
$res = $mysqli->query($q) or trigger_error($mysqli->error."[$q]");
$array = array(); // initialize
while($row = $res->fetch_array(MYSQLI_BOTH)) {
$array[] = array(
'key' => $row[0],
'username' => $row[1],
// ... continue like this
);
}
header('Content-Type: application/json');
echo json_encode($array);
$res->free();
$mysqli->close();
Now, the above script seems to work fine. At least it displays just fine when loading the php page in the browser.
But when I make an ajax call with this script:
$(document).ready(function(){
$.ajax({
type: "POST",
url: "queries.php",
dataType: 'json',
data: "",
cache: false,
success: function(result)
{
var cfkey = result[0];
var user = result[1];
alert("cfkey:" + cfkey + "user:" + user);
}
});
});
After loading this code, the chrome console states that the server returned with error 500.
Again, what I am trying to accomplish:
I would like to be able to make an ajax request for say, and ID, then get back all of that ID's corresponding data, (wrapped in Json - At least I think it needs to be..).
With the ajax script, I would like to be able to save the returned corresponding data to an input field in html.
EDIT:
Finally figured out that the problem I was discussing with Majid was with the SQL query.
key needed to be need to be wrapped in ` characters.
After you execute your query and the resultset is available in $res you could just build up your array, no need for a separate foreach:
$array = array(); // initialize
while($row = $res->fetch_array(MYSQLI_BOTH)) {
$array[] = array(
'id' => $row[0],
'username' => $row[1],
'password' => $row[2],
'nick' => $row[3],
'addr' => $row[4],
'facebook' => $row[5],
'twitter' => $row[6],
'linkedin' => $row[7],
'youtube' => $row[8]
);
}
header('Content-Type: application/json');
echo json_encode($array);
Also note that this way, your json will have keys, so to consume it you should change:
success: function(result) {
var cfkey = result[0];
var user = result[1];
alert("cfkey:" + cfkey + "user:" + user);
}
To
success: function(result) {
var cfkey = result.id;
var user = result.username;
alert("cfkey:" + cfkey + "user:" + user);
}
Or simply do
$.getJSON('queries.php', {cfkey: $("#cfkey").val()}, function(result) {
// we have multiple results
$.each(result, function(i,r) {
console.log("cfkey:" + r.key + "user:" + r.username);
});
});
Edit: added header as pointed out by #amurrell
I believe you are expecting queries.php to return json (to your ajax) and thus you need content header types in your queries.php!
header('Content-Type: application/json');
You need more useful error messages. Try adding the following lines at the beginning of your code.
error_reporting(E_ALL);
ini_set("display_errors", 1);
Your script that outputs JSON is writing several valid JSON strings (one for each database row), but they don't add up to a valid JSON file. A JSON file should represent one JSON object.
If you want to pass an ID and get one database row back, you have to add that ID to the data part of your AJAX call, and modify queries.php to pass that id from its $_POST array into the WHERE part of your MySQL query. Then, you'd only output one JSON-encoded object rather than many, which would be a valid JSON file.
(Alternately, you could json_encode() the entire $rows array rather than each $row individually if you want the whole table back.)
Also, if you json_encode() a string-indexed array in PHP, you read its properties in Javascript by name, not by index. You've gone through the trouble of naming your keys in PHP, then switch back to trying to reference them by their 0-based index in Javascript. You can pick one way or the other, but you can only pick one!

PHP json_encode to JS object not usable

I have an some PHP that looks like this:
$exec[0] = shell_exec("cat /etc/msm.conf | grep JAR_PATH");
$exec[1] = shell_exec("msm server list");
if(strstr($exec[1],'[ ACTIVE ] "mc-srv" is running. Everything is OK.') !== FALSE){
$exec[1] = 'mc online';
}else{
$exec[1] = 'mc offline';
}
$exec[2] = shell_exec("sudo ts status");
if($exec[2] == 'Server is running'){
$exec[2] = 'ts online';
}else{
$exec[2] = 'ts ofline';
}
echo json_encode($exec,JSON_FORCE_OBJECT);
An AJAX request gets sent to the page and the json is returned.
If I use console.log(JSON.parse(data)) I see this in the console Object {0: "DEFAULT_JAR_PATH="server.jar"↵", 1: "mc online", 2: "ts ofline"} however I can not access any of its methods even if i use an associative array.
but If i create a new object and print that to the console it (in chrome atleast) looks exactly the same in terms of syntax highlighting exect I can access it via obj.method.
What am I doing wrong here?
Based on how the object is being output in the console, it looks like it's being parsed okay by JSON.parse and is valid.
In which case, you should be able to access each method like this:
var obj = JSON.parse(data);
console.log( obj['0'] ); // returns "DEFAULT_JAR_PATH="server.jar""
console.log( obj['1'] ); // returns "mc online"
obj.0 won't work in this case because the method names are numbers.

Communication between Javascript and MYSQL

I am working on some code using Google Maps API. To sum up shortly, I have MySQL database with a table of information used to generate markers on the map. I connected to the database and am using PHP to draw out the necessary attributes and communicate with my Javascript code using XML.
What I'm currently attempting to do is go in the other direction, I'm trying to send a string of information (for example "1,2,3,45,18") from my Javascript code to MySQL to be set as a session parameter (call it #sparam). What is the process behind passing this value to MySQL?
Would I be able to access a MySQL variable through PHP in the same way I can access tables (for the purpose of getting a value back into Javascript)?
I'd appreciate any insight.
Thanks.
EDIT
Maybe I was unclear in my original post. What I'm asking is how would I be able to pass a string to a MySQL session variable, specifically a set of IDs directly related to the IDs in the table of the MySQL database, and then be able to work with these IDs by calling the necessary procedures in MySQL. In turn, the procedures called in MySQL would generate some output, which would then have to be passed back to the Javascript code.
I created a special JSON (JavaScript Object Notation) php pages that I would call from javascript. Then I would parse those JSON responses.
Simple example:
JAVASCRIPT:
function getCheckedUnits() {
jQuery(function($) {
$.ajax( {
url : "page_json.php?action=getsession",
type : "GET",
success : function(data) {
//Get Json and loop over it's data
if (data.length>10){
var jsonData = JSON.parse(data);
$.each(jsonData, function(Idx, Value) {
if (Idx>0){
//get values for each vehicle and then remove it's marker from the map and then add new marker on the map (thereofore update the marker)
c_latitude = Value["lat"];
c_longitude = Value["lon"];
c_name = Value["name"];
c_notes= Value["notes"];
removeMarker(c_name); //remove old marker function
addMarker(c_latitude, c_longitude, c_name); //add current marker function
}
});
}
}
});
});
}
PHP: Here I loop over my arrayList and then create a simple array with values. Then I just output it as a json string
foreach ($listOfCars->arrayList as $key => $value) {
$unit = new fleetUnit();
$unit = $value;
//create array for json output
$data[] = array('lat' => $unit->lat,
'lon' => $unit->lon, 'name' => $unit->name, 'notes' => $unit->notes);
}
echo json_encode($data);

Categories