jQuery: How to iterate through JSON encoded string (array) - php

I am a jQuery beginner and hope someone can help me with this and also provide me some explanations.
I have an Ajax call that returns a JSON encoded string with two values for each item, an itemID and an itemVal - an example looks as follows (using console.log):
console.log(data) result:
string(225) "[{"itemID":1,"itemVal":"China"},{"itemID":2,"itemVal":"France"},{"itemID":3,"itemVal":"Germany"},{"itemID":4,"itemVal":"Italy"},{"itemID":5,"itemVal":"Poland"},{"itemID":6,"itemVal":"Russia"},{"itemID":7,"itemVal":"USA"},...]"
The number of items here varies but if an itemID is listed than there is always a corresponding itemVal.
itemID is a unique integer, itemVal is plain text.
Everything works so far but here comes my problem:
For each itemID here I have to do something with the corresponding itemVal, e.g. say just log it to the console or alert it for testing.
I know there are various approaches for this like jQuery.each, $.each, for, foreach etc. but since I just started recently I am not sure how I can iterate through this resp. how I can select the single itemIDs from it.
I tried different approaches, incl. $.parseJSON(data) which failed and it seems the problem is that my input before being decoded is a two-dimensional array instead of a one-dimensional one (I hope I am using the right terms here) which caused them to either return an error or to alert every single character of my string.
Update - failing example as per the answer below
$.ajax({
type: "post",
url: "ajax.php",
cache: "false",
data: {
node: 'fetchCountries',
itemIDs: itemIDs // a list of integers
},
success: function(data){
console.log(data);
var arr = JSON.parse(data);
$.each($(arr),function(key,value){
console.log(value.itemVal);
});
}
});
Update 2 - My PHP:
case "fetchCountries":
$intval_itemIDs = array_map("intval", $_POST["itemIDs"]);
$itemIDs = implode(",", $intval_itemIDs);
$stmt = $conn->prepare("SELECT itemID, en FROM Countries WHERE itemID IN(" . $itemIDs . ") ORDER BY itemID");
$stmt->execute();
$result = $stmt->get_result();
while($arrCountries = $result->fetch_assoc()){
$countries[] = array("itemID" => $arrCountries["itemID"], "itemVal" => $arrCountries["en"]);
}
var_dump(json_encode($countries));
break;
Expected outcome (for testing):
console.log("China");
console.log("France");
console.log("Germany");
// ...
Can someone help me with this ?
Many thanks,
Tim

You have a JSON string representing an Array, which you are parsing into an actual Array. Then you are looping through the array, pushing each element into a new Array (arr).
Perhaps there is some confusion. Hopefully this will shed some light.
// Considering the following JSON string:
var data = '[{"itemID":1,"itemVal":"China"},{"itemID":2,"itemVal":"France"},{"itemID":3,"itemVal":"Germany"},{"itemID":4,"itemVal":"Italy"},{"itemID":5,"itemVal":"Poland"},{"itemID":6,"itemVal":"Russia"},{"itemID":7,"itemVal":"USA"}]';
// You can create an Array from this like so:
var theArray = JSON.parse(data);
// Now you have an array with each item being an `object`
// with an "itemId" and an "itemVal". You can loop through
// this array and look at each object like so:
theArray.forEach(function (obj) {
console.log(obj.itemID + ': ' + obj.itemVal);
});

WhistleBlower, I have tested your code on my browser. It worked. Why don't you use header("Content-type :application/json"); too. So, you will not have to parse your JSON string.
var data = '[{"itemID":1,"itemVal":"China"},{"itemID":2,"itemVal":"France"},{"itemID":3,"itemVal":"Germany"},{"itemID":4,"itemVal":"Italy"},{"itemID":5,"itemVal":"Poland"},{"itemID":6,"itemVal":"Russia"},{"itemID":7,"itemVal":"USA"}]';
var arr = JSON.parse(data);
$.each($(arr),function(key,value){
console.log(value.itemVal);
});

You're not parsing a string, you're parsing an already-parsed object
just use it directly
var data=[{"itemID":1,"itemVal":"China"},{"itemID":2,"itemVal":"France"},{"itemID":3,"itemVal":"Germany"},{"itemID":4,"itemVal":"Italy"},{"itemID":5,"itemVal":"Poland"},{"itemID":6,"itemVal":"Russia"},{"itemID":7,"itemVal":"USA"}];
$.each(data,function(key,value){
console.log(value.itemVal);
});
or/
var arr = JSON.parse(JSON.stringify(data));
$.each(arr, function (key, value) {
console.log(value.itemVal);
});
Update 1:
I think so your php file like
<?php
$array = array( array( 'itemID' => 1, 'itemVal' => 'India'), array( 'itemID' => 2, 'itemVal' => 'usa'), array( 'itemID' => 3, 'itemVal' => 'china'), array( 'itemID' => 4, 'itemVal' => 'uk'));
echo json_encode($array);
//[{"itemID":1,"itemVal":"India"},{"itemID":2,"itemVal":"usa"},{"itemID":3,"itemVal":"china"},{"itemID":4,"itemVal":"uk"}]
?>
your script should be
$.getJSON( "your.php", function( data ) {
console.log(data);
$.each(data, function (key, value) {
console.log(value.itemVal);
});
});
OR
$.ajax({
type: "post",
url: "your.php",
cache: "false",
dataType: 'json',
data: {
node: 'fetchCountries',
itemIDs: youval // a list of integers
},
success: function(data){
console.log(data);
var arr = JSON.parse(JSON.stringify(data));
$.each($(arr),function(key,value){
console.log(value.itemVal);
});
}
});
OR
$.ajax({
type: "post",
url: "your.php",
cache: "false",
dataType: 'json',
data: {
node: 'fetchCountries',
itemIDs: youval // a list of integers
},
success: function(data){
console.log(data);
$.each($(data),function(key,value){
console.log(value.itemVal);
});
}
});

As simple as this!
$.each($(data),function(key,value){
console.log(value.itemVal); //place alert if you want instead of console.log
});
iterate through the obtained result and get itemVal value of each item
DEMO HERE
UPDATE
Add dataType option to your ajax and return type from php should be json and I hope you are doing that!
$.ajax({
type: "POST",
url: "ajax.php",
cache: "false",
dataType:'json', //Add this
data: {
node: 'fetchCountries',
itemIDs: itemIDs // a list of integers
},
success: function(data){
console.log(data);
var arr = JSON.parse(data);
$.each($(arr),function(key,value){
console.log(value.itemVal);
});
}
});
and return from your php should be echo json_encode(result);

Thanks to everyone for the help with this.
Since all other approaches made sense to me but still failed I did some more research on this and finally found what was causing this.
The issue was indeed on the PHP side and the accepted answer on the following post did the trick - since I added this to my PHP everything else on the JS side is working fine and I don't even need the dataType: "JSON" there:
dataType: "json" won't work
As per this post the solution for my case is the following - kudos to Jovan Perovic:
<?php
//at the very beginning start output buffereing
ob_start();
// do your logic here
// right before outputting the JSON, clear the buffer.
ob_end_clean();
// now print
echo json_encode(array("id" => $realid, "un" => $username, "date" => $date));
?>
Thanks again.

Related

How to loop through multi dimensional array response from Ajax in Jquery?

I am trying to get the quantity of raw materials along with the raw material id. I send recipe id and in response I am getting array like this
[54,"Vanilla Cake Mix",2000] [126,"Water",1200] [1,"Refined Soyabean Oil",200]
Where 54 is Raw Material ID,
Vanilla Cake Mix is Raw Material Name,
And 2000 is Quantity
How do I access each value of this?
My Jquery code is
`$.ajax({
type:"POST",
url:"api_consumption.php",
data: "product_recipe_id="+product_recipe_id+"&quantity="+value,
dataType: "json",
success: function(html)
{
//I want to access the values received in json array format.
}
});`
My PHP code is
$array = array($raw_material_id, $raw_material_name, $raw_material_quantity);
echo json_encode($array);
I tried the each loop but failed.
Sample Output:
When I comment this code dataType: "json",
and alert(html), I get this
Sample Output
If you only need to alert the data, you can just simply convert the data:
success: function(html)
{
let data = JSON.parse(html);
alert(data);
}
But I believe you will need it in a textbox or dropdown, that's when you can loop through each data.
success: function(html)
{
let jsonData = JSON.parse(html);
let data = '';
$.each(jsonData, function(key, value){
data+= '<option value="'+jsonData[key][0]+'">'+ jsonData[key][0] +
' - '+ jsonData[key][1] +' - '+ jsonData[key][2] +'</option>';
});
$('#dropdown-id').html(data);
}

Can't return json array from PHP to jQuery AJAX

Problem
I am using AJAX jQuery with a dropdown to get some response from PHP. So far i wanted just one row from database, but now i want another array.
Current situation
front -
$.ajax({
type: "POST",
url: "project_details.php",
data: data_string,
cache: false,
success: function(data){
if(data){
var json = data;
obj = JSON.parse(json);
$("#project-name").text(obj.project_name);
$("#start-date").text(obj.start_date);
}
}
});
back -
$result=mysqli_query($db,"SELECT distinct project_name,start_date FROM `projects` WHERE a.supervisor_email = '$email' and a.project_id = '$project'");
$count=mysqli_num_rows($result);
$row=mysqli_fetch_array($result,MYSQLI_ASSOC);
if($count==1){
echo json_encode(array("project_name" =>$row['project_name'],
"start_date" => $start->format("d M,Y"))); }
What I want -
I need another array returned from PHP -
$result_1=mysqli_query($db,"SELECT member_email FROM `projects` WHERE a.supervisor_email
$email' and a.project_id = '$project'");
$row_1=mysqli_fetch_array($result,MYSQLI_ASSOC);
so the final echo should be something like
if($count==1){
echo json_encode(array($row_1,"project_name" =>$row['project_name'],
"start_date" => $start->format("d M,Y"))); }
I can't figure out how to read this from jQuery
Note that table I'm using is at project_id, member_email level
First of all, specify the datatype as json.
This way you do not need..
var json = data;
obj = JSON.parse(json);
..and you can use the data variable directly. Also, depending on what you are doing with the AJAX data, it may be better to use .html() instead of .text().
In regards to your original question, I see that you have added $row_1 to your existing array but it will not work that way. I don't know what it contains, but seems to be an array. Since AJAX is expecting json format you need to have key=>value pairs. How about like this?
PHP:
$json_arr = array();
while ($row_1=mysqli_fetch_array($result,MYSQLI_ASSOC)) {
$email{'member_email'] = $row_1['member_email'];
}
if($count==1){
echo json_encode(array("member_email" =>$email,
"project_name" =>$row['project_name'],
"start_date" => $start->format("d M,Y")));
}
AJAX:
$.ajax({
type: "POST",
url: "project_details.php",
data: data_string,
dataType: "json",
cache: false,
success: function(data){
if(data){
$("#member_email").text(data.member_email);
$("#project-name").text(data.project_name);
$("#start-date").text(data.start_date);
}
}
});
I'm not exactly sure if I got your question right. But you would like to have $row_1 as additional array to be echoed, am i right? If so, Try this:
PHP
echo json_encode( array(
"row_1" => $row_1,
"project_name" =>$row['project_name'],
"start_date" => $start->format("d M,Y")
)
);
Then on your $.ajax
use data.row_1 , data.project_name, data.start_date to refer to your encoded value
Note: I would also like to recommend what #EternalHour said that you should use dataType: 'json' instead for a much cleaner approach, and it seems to be easier that way too.
Please tell me if my recommended code worked. If not would you please tell me the error that comes with it too.
Do you get what you want when you do a console.log(obj); ?
Cause there is no "project_name" inside
your SQL-Select
Regarding jQuery .. tried $.each?
$.each(obj, function(key, project)
{
...text(project.project_name);
});

Multiple Arrays returned by json from PHP

To begin with I am building a complete CRM running Ajax and there is a lot to this, so please be patient and read the whole thing.
I have an ajax script returning several json arrays. When I display the return value from my php script I get this:
[{"packages":{"id":"1","name":"Land Line"}},{"packages":{"id":"2","name":"Cellular w\/Alarm.com"}},{"packages":{"id":"3","name":"Home Automation"}}]
What I am trying to do is separate the arrays so I can make a select drop down from it. Before anyone says anything, yes I know how to do that my itself, but I am needing the form this script is populating to be a select dropdown or a complete filled in form based off of the id going into another script. It is a bit confusing, so don't ding me for it please.
Here is the PHP script alliance_form.php:
$equip = "SELECT * FROM packages WHERE brand='$brand'";
if($db->query($equip) === false) {
trigger_error('Wrong SQL: ' . $query . ' Error: ' . $db->error, E_USER_ERROR);
} else {
$result = $db->query($equip);
$array = array();
foreach($result as $r) {
$array[] = array(
"packages" => array(
"id" => $r['id'],
"name" => $r['name']
)
);
}
echo json_encode($array);
}
Here is the jquery going to the PHP form and coming back to input the information:
$.ajax({
type: "POST",
url: "/crm/alliance_form.php",
data: dataString,
success: function(msg)
{
$("#package-form").html(msg);
$.each(msg.packages, function(i, object) {
$.each(object, function(index, value) {
alert(value);
});
});
},
error: function(error)
{
$(".error").html(error);
}
});
This is part of an ordering system of a CRM, so this script is checking the database for existing orders under the id. If the id is there then it is supposed to come back with the order information and I populate the form. If not it will give a select dropdown to select a package which then populates an empty form. That is the gist of what I am on right now.
Here is the question: Why can't I get a response from JQuery on the each() loop on this. One return comes back with a regular array, and this one is a nested array.
I'm not quite clear on what you're asking, but here are my thoughts on this:
You've got .packages in the wrong place. Instead of this:
$.each(msg.packages, function(i, object) {
$.each(object, function(index, value) {
...
You should have written this:
$.each(msg, function(i, object) {
$.each(object.packages, function(index, value) {
...
Better yet, you could just get rid of packages altogether. It's an unnecessary level in the JSON structure.
Also, I don't think jQuery knows that the response is JSON. For this to work, you need either dataType: 'json' in the list of arguments to $.ajax, or something on the server to set the MIME type appropriately.
I'm also concerned about $("#package-form").html(msg);, because msg is not an HTML string.
You should try something like this (Example)
msg = $.parseJSON(msg); // parse JS to object
$.each(msg, function(i, object) {
$.each(object.packages, function(index, value) {
console.log(value);
});
});
Instead of $.each(msg.packages, function(i, object){...}) because msg is an array of objects and in your given example there are three objects right now and each object has a packages item (nested object) which contains id and name.
Update : You can also use, just one loop (Example)
msg = $.parseJSON(msg); // parse JS to object
$.each(msg, function(i, object) {
console.log(object.packages.id);
console.log(object.packages.name);
});
Sorry guys, I threw out my back and couldn't get to my code from home.
Anyways I tried both solutions you provided, and I have been looking at this for a while but neither worked. I have this updated to:
$("#brand").click(function () {
var brand = $(this).attr('rel');
$("#order-form").empty();
var contact_id = $("#contact_id").val();
var dataString = "contact_id=" + contact_id +"&brand=" + brand + "";
//alert("test");
$.ajax({
type: "POST",
url: "/crm/alliance_form.php",
data: dataString,
//dataType: "json",
success: function(msg)
{
//$("#package-form").html(msg);
$.each(msg, function(i, object) {
if(msg.packages) {
$("#package-form").append("<select>");
$.each(object.packages, function(index, value) {
$("#package-form").append('<option value="'+value+'">'+index+'</option>');
});
$("#package-form").append('</select>');
}
});
},
error: function(error)
{
$(".error").html(error);
}
});
});
This just returns nothing not even a blank select box. The $("#package-form").html(msg); is just so I can see the output how the php script is sending it back. The if statement is just to run a verification to see if the array has a nested array with packages in it. I need the return function to do a certain action if it does. Very Important!
As for the dataType: 'json', line in the ajax, it doesn't give me a return value if I have that placed in it. But when I remove it, it will display the array.
Nothing has been changed in the PHP file besides moving the query like suggested.
Ok guys. I got the answer! I have it like this:
$("#brand").click(function () {
$("#order-form").empty();
$("#package-form").empty();
var msg = '[{"packages":{"1":"Land Line"}},{"packages":{"2":"Cellular w\/Alarm.com"}},{"packages":{"3":"Home Automation"}}]';
var newData = JSON.parse(msg);
var newSelect = "<select>";
$.each(newData, function(i, ob) {
$.each(ob.packages, function(index, value) {
newSelect += '<option value="'+index+'">'+value+'</option>';
});
});
newSelect += "</select>";
$("#package-form").append(""+newSelect+"");
});
Here is the fiddle: http://jsfiddle.net/M78vE/

Splitting a JSON Array with JQuery that has been returned by PHP

I am new to JQuery and the whole JQuery to PHP back to JQuery process.
So i have a simple ajax JQuery script:
$.ajax({
type: "POST",
url: "includes/calc.php",
data: {
'var1':var1,
'var2':var2,
},
success: function(data){
alert(data);
$("input#hiddenprice").val(data);
$('#'+itemprice).html("€"+data);
}
})
This goes to a PHP script and then I return a value, using a simple echo
echo $newprice;
The success function above uses this as 'data'. This all works and is fine.
But what if I want to return more than one value.
I think I can used json_encode();
As I understand it something like:
$dataset = array($var1, var2, var3);
echo json_encode($dataset);
But say I have two values, how do i put them both into the JSON and then how do I split them on the other end.
So say 'data' is an array, how do I tell JQuery to split it?
Sorry if this is simple
If you specify the dataType option for .ajax() as json, jQuery will automatically parse the JSON string returned by the call into an appropriate javascript object/array.
So your call might look like this:
$.ajax({
type: "POST",
url: "includes/calc.php",
dataType: "json",
data: {
'var1':var1,
'var2':var2,
},
success: function(data){
alert(data);
$("input#hiddenprice").val(data);
$('#'+itemprice).html("€"+data);
}
})
Now, let's say the response from your PHP script is a JSON string representing an object like this:
{"key1":"value1","key2":"value2"}
In your success handler you can simply access this as an object like this:
success: function(data){
alert(data.key1);
alert(data.key2);
}
Or, if the returned JSON string represents an array like this:
["value1","value2"]
Then you can access the array values in the success handler like this:
success: function(data){
alert(data[0]);
alert(data[1]);
}
If you do not want to add the dataType option, you can also opt to manually parse the returned JSON string into an object/array like this:
success: function(data){
var dataObj = JSON.parse(data);
alert(dataObj.key1);
alert(dataObj.key2);
}
$.ajax({
type: "POST",
url: "includes/calc.php",
datatype : 'json',
data: {
'var1':var1,
'var2':var2,
},
success: function(data){
alert(data.firstvalue);
alert(data.secondvalue);
}
})
please look at that datatype. now the respose need to be json.
In your php user json_encode instead of echo.
$firstvalue = 'your first value';
$secondvalue = 'your second value';
echo json_encode(array('firstvalue' => $firstvalue,'secondvalue' => $secondvalue));
There are many ways to organize data in a JSON object. The simplest is to return a linear array of strings or numbers. Use http://jsonlint.com/ to test your data to see if it's valid JSON, or just feed a PHP array (linear or associative) into json_encode.
If data is a JSON linear array, you can treat it like any other JavaScript array in your success callback:
var first = data[0]; // first element
var second = data[1]; // second element
implode your php variables with a symbol or any custom data
like
$var[0] = '1st variable';
$var[1] = '2nd variable';
$var[2] = '3rd variable';
echo implode('_SPLIT_',$var);
Now in jquery success function
split the response with 'SPLIT'
as
var response = data.responseText.split('_SPLIT_');
var variable1 = response[0];
var variable2 = response[1];
var variable3 = response[2];
and assign as your wish

How can I use the data I get from my database using MySQLi, in Bootstrap typeahead?

I'm using jQuery ajax + MySQLi's prepared statements to get data from my database. The problem is that I don't know how to exactly format the data to use in Bootstrap's typeahead plugin.
This is the relevant code:
PHP:
$stmt = $mysqli->prepare("SELECT GAME_NAME FROM GAMES WHERE GAME_NAME LIKE ?");
$query = "%".$query."%";
$stmt->bind_param('s',$query);
$stmt->execute();
$stmt->store_result();
$count = $stmt->num_rows;
if($count > 0) {
$stmt->bind_result($result);
while($stmt->fetch()) {
echo json_encode($result);
}
What I get as AJAX response is all the names as a bunch of text:
'"game 1""game 2""blaablaa""some other game"....'
I think I have to have an array of names and I don't know how to get the stmt result as an array. The example I tried and works is (I use the array allCities as data-source):
<script type="text/javascript">
$(document).ready(function() {
var allCities = ['Baltimore', 'Boston', 'New York', 'Tampa Bay', 'Toronto', 'Chicago', 'Cleveland', 'Detroit', 'Kansas City', 'Minnesota', 'Los Angeles', 'Oakland', 'Seattle', 'Texas'].sort();
$('#city').typeahead({source: allCities, items:5});
});
</script>
Now if I only could get result in the same format as in the example, my problem should be solved, I think. Btw, I'm not sure about the json_encode() I used in the code. That's just something I gave a try. I appreciate any help. Thanks.
UPDATE, Ajax:
function handleSearch() {
var query = $.trim($('#search-field').val());
var itm = getSearchItem();
$.ajax({
type: "POST",
url: "..//functions/handleSearch.php",
dataType: "json",
data: "query="+query+"&itm="+itm,
success: function(resp) {
console.log("Server said (response):\n '" + resp + "'");
$('#search-field').typeahead({source: resp});
},
error: function(e) {
console.log("Server said (error):\n '" + e + "'");
}
});
another update:
In Network tab the response gives the result I want but in this format: Resistance: Fall of ManResident Evil 4John Woo Presents StrangleholdAge of Empires II: The Age of KingsResident Evil 2. So without any formatting. Console.log(resp) gives me nothing though. Although when I search for "resident evil 6", that means when I type in the EXACT NAME, console.log also works.
Basically you should create key=>value store array and then in the end you should output it with json_encode. What you are doing wrong in your code is you are trying to echo and json_encode on every result which should be done just in the end.
post the code that initializes ajax request.
For example this is shorthand for jquery ajax function
$.ajax({
url: url,
dataType: 'json',
data: data,
success: callback
});
if data type specified json then callback function will receive an array like allCities in your example then you can pass it to your plugin. For example pseudo code:
$.ajax({
url: 'http://blabla',
dataType: 'json',
data: dataArray,
success: function(response) {
$('#city').typeahead({source: response, items:response.count()});
}
});

Categories