Appending JSON array to select - javascript

I am trying to append this JSON array to a select box
{
"10":"Branche",
"2":"Marketing & Comunicatie",
"8":"Test Branche 1",
"9":"Test Branche 2",
"6":"Test Branche 3",
"7":"Test Branche 4",
"1":"Webdevelopment & design"
}
But it doesn't work I encoded it from a PHP array. This is how I am trying to loop through it.
this.addOption = function(name, table, value){
$.ajax({
type: "POST",
data: {action:'add', table:table, value:value},
url: "index.php",
})
.done(function( obj ) {
$("#"+name+"-select").empty()
console.log(name);
$.each(obj, function( key, value ) {
$("#"+name+"-select").append('<option value='+key+'>'+value+'</option>');
});
});
}
Where obj is the JSON array.
It is giving me this error:

It appears that your PHP is outputting the JSON with a content type of text/html and because you haven't told jQuery you're expecting JSON, it won't parse the response, and in the end you're trying to call $.each on a string.
Add a dataType to tell jQuery to explicitly parse the response as JSON:
$.ajax({
type: "POST",
data: {action:'add', table:table, value:value},
url: "index.php",
dataType: 'json'
})
Alternatively, set the correct content type in your PHP:
header('Content-type: application/json');
echo json_encode(...);

Yes you can use following way:
for(k in obj) {
$("#branch-select").append('<option value='+k+'>'+obj[k]+'</option>');
}

Related

Ajax sends two empty arrays and one filled, PHP receives only the full one

I'm completely new to PHP. Working with ajax, php and WordPress I'm sending an object with ajax:
let import_data = {
action: 'import_data',
data: {
first_array: [], // this one is empty
second_array: [], // this one too
third_array: [1,2,3] // this one is full
}
};
I've checked the import_data object many times right before it was sent. The php, however, always receives:
import_data = {
action: 'import_data',
data: {
third_array: [1,2,3]
}
}
The question is why is that happening and how can I achieve receiving all arrays, whether they are empty or not, i.e.
import_data = {
action: 'import_data',
data: {
first_array: [],
second_array: [],
third_array: [1,2,3]
}
}
I need to refactor a lot of code now due to this issue so I'm trying to solve it as easy as possible, but if there is a common known right way to deal with it I'll use it. Thanks in advance!
P.S. In case you wondering, yes, if all arrays being sent are full, php will receive all of them.
UPD In the comments I got I might've wanted to add contentType or json.strngify my data. It didn't help, but I might do it wrong, so I'll try to partly show my code below:
var import_data = {
action: 'start_import',
sliced_batch: {
rows_to_add: [],
rows_to_delete: [],
rows_to_update: [1,2,3,4,5,...]
}
};
function ajax_call(import_data) {
// ... processes
jQuery.ajax({
url: start_import_ajax.url, // url from php file
type: 'POST',
contentType: "text; charset=utf-8", // sending string with cyrillic (ukrainian lng)
dataType: 'application/json', // want to recieve json
data: JSON.stringify(import_data),
success: function(response) {
// ... processes import_data ...
if(it is the end of data) return;
else ajax_call(import_data);
},
error: function(e) {
// here is where I end up
}
}
PHP side is now pretty shy, as I just made a pause and wanted to see my data in console:
function start_import_callback() {
echo json_decode($_POST);
echo $_POST;
echo json_decode($_POST['sliced_batch']);
echo $_POST['sliced_batch'];
wp_die();
}
I've tried all echo's one by one, but always saw:
{
"readyState": 4,
"responseText": "0",
"status": 400,
"statusText": "error"
}
When NOT stringifying and NOT specifying contentType/dataType it returns:
{
action: 'import_data',
sliced_batch: {
rows_to_update:
{
"ID": "00000006125",
"CatalogueNumber": "bla, bla",
"Category": "bla, bla",
"Manufacturer": "bla",
"Nomenclature": "blablablablabla",
"NomenclatureUkrainian": "bla",
"StockStatus": "instock",
"Price": "2 315",
"Parent": "blabla",
"Sorting": "99"
},
{},...
]
}
}
So, rows_to_delete: [] and rows_to_add: [] are missing...
You are using jQuery dataType options wrong!
The dataType: value should be 'json' not 'application/json' because your value will request with HTTP accept: */* but if you use 'json' it will be accept: application/json.
Option 1
Use content type application/json.
The contentType: should be 'application/json' or 'application/json;charset=utf-8'.
By this content type you will be now able to receive POST data in JSON but you cannot access them with $_POST because the data is not valid application/x-www-form-urlencoded.
Full code for client side:
var import_data = {
action: 'start_import',
sliced_batch: {
rows_to_add: [],
rows_to_delete: [],
rows_to_update: [1,2,3,4,5]
}
};
function ajax_call(import_data) {
// ... processes
jQuery.ajax({
url: 'test.php', // url from php file
type: 'POST',
contentType: "application/json;charset=utf-8", // sending string with cyrillic (ukrainian lng)
dataType: 'json', // want to recieve json
data: JSON.stringify(import_data),
success: function(response) {
// ... processes import_data ...
},
error: function(e) {
// here is where I end up
}
});
}
Code for PHP:
$data = json_decode(file_get_contents('php://input'), true);
// use $data['sliced_batch'] to access `rows_to_add`, `rows_to_delete` etc.
Option 2
Use content type application/x-www-form-urlencoded.
With this content type, you will be able to access $_POST properly.
However, to use this request content type in header, the jQuery itself will be modify the value if it is empty jQuery will be just delete it!! So, you need to JSON string only sliced_batch property.
Here is the JS code:
var import_data = {
action: 'start_import',
sliced_batch: {
rows_to_add: [],
rows_to_delete: [],
rows_to_update: [1,2,3,4,5]
}
};
function ajax_call(import_data) {
// ... processes
// modify `sliced_batch` property to be JSON string to prevent jQuery remove empty properties.
import_data.sliced_batch = JSON.stringify(import_data.sliced_batch);
jQuery.ajax({
url: 'test.php', // url from php file
type: 'POST',
// just remove contentType option. It is no need.
//contentType: "application/json;charset=utf-8", // sending string with cyrillic (ukrainian lng)
dataType: 'json', // want to recieve json
data: import_data,
success: function(response) {
// ... processes import_data ...
},
error: function(e) {
// here is where I end up
}
});
}
PHP:
$sliced_batch = ($_POST['sliced_batch'] ?? '');
$sliced_batch = json_decode($sliced_batch, true);
// you can now access $sliced_batch['rows_to_add'], etc...
So, thanks once again to #vee for his explanation, but here's one more thing I'd like to share as it was crucial to get everything to work.
First, for json_decode method the JS object keys should be double-quoted, i.e. NOT
$bad_json = '{ bar: "baz" }';
json_decode($bad_json); // null
or
$bad_json = '{ 'bar': "baz" }';
json_decode($bad_json); // null
BUT
$bad_json = '{ "bar": "baz" }';
json_decode($bad_json); // array("bar" => "baz")
Second and most important!
When dealing with WordPress it sets its own rules and shows focuses!
Depending on what answer you'd like to get, you may want to use function wp_unslash(). Looking at the stringified data in console I saw somth like this:
"\u0421\u0435\u0440\u0432\u0435\u0440: \u0424\u0430\u0439\u043b\u0456\u0432 av_imp_p_WEB.csv \u0456 av_imp_p_WEB_previous.csv \u043d\u0435 \u0431\u0443\u043b\u043e \u0432\u0438\u044f\u0432\u043b\u0435\u043d\u043e. \u041f\u043e\u0447\u0438\u043d\u0430\u044e \u0456\u043c\u043f\u043e\u0440\u0442 \u0432\u0441\u044c\u043e\u0433\u043e
// it is more common for contentType: "application/x-www-form-urlencoded"
It is the dirty work of WooCommerce (as I read from another's people opinion) and it hinders parsing it the right way, so my full code is:
JS
var import_data = {
"action": "start_import",
"sliced_batch": {
"rows_to_add": my_data1,
"rows_to_delete": my_data2,
"rows_to_update": my_data3
}
};
function ajax_call(import_data) {
// ... processes
jQuery.ajax({ // ajax to php to save the file to uploads and move it to the plugin's folder
url: start_import_ajax.url, // url from php file
type: 'POST',
//contentType: "application/json;charset=utf-8", // what you send
dataType: 'JSON', // what you would like as a response
data: {
"action": import_data.action,
"sliced_batch": JSON.stringify(import_data.sliced_batch)
},
success: function(response) {
//response = JSON.parse(response); // if you'd like to console.log what you've sent
console.log(response);
}
....
PHP
$sliced_batch = wp_unslash($_POST['sliced_batch']);
$sliced_batch = json_decode($sliced_batch, true);
$result = start_import($sliced_batch);
if($result == 0) {
echo json_encode(["status" => 0]);
} else echo json_encode(["status" => 1]);

Pass map array to a PHP page

For my project, I'm using this:
var arr = new Map(); to create a map with JS.
After each click on elements, I'm using this to populate the map.
arr.set(roomid + '_' + date, {
status: updatedStatus,
date: date,
roomid: roomid
});
After few clicks, on the console panel, I have:
[Log] Map {"48_2019-03-09" => {status: "Open", date: "2019-03-09", roomid: 48}, "48_2019-03-19" => {status: "Open", date: "2019-03-19", roomid: 48}} (2) (app.js, line 93)
So, this is what I want.
Now I need to pass this datas to PHP via Ajax like this:
$.ajax({
type: 'POST',
data: { datas: arr },
url : 'update.php',
success: function(responseText){
...
}
});
On my PHP page, I have the following code:
$arr = $_POST;
print_r($arr);
But this code output:
Array
(
)
But this doesn't work because my PHP page print an empty array.
What I'm doing wrong please ?
Thanks.
you need to convert the map to a json object. Easiest way I know to do this is to stringify and then parse to a JSON object.
JSON.parse(JSON.stringify([...arr]))
$.ajax({
type: 'POST',
data: { datas: JSON.parse(JSON.stringify([...arr])) },
url : 'update.php',
success: function(responseText){
...
}
});
Ref: http://2ality.com/2015/08/es6-map-json.html
Ajax expects an object, not a Map. So you need to convert your Map to an object before passing it to the ajax request.
function mapToObject(map) {
var obj= {}
map.forEach(function(value, key) {
obj[key] = value
}
return obj
}
....
$.ajax({
type: 'POST',
data: { datas: mapToObject(arr) },
url : 'update.php',
success: function(responseText){
...
}
});
EDIT: just noticed, if you need to pass a full JS object to PHP you need to convert it to JSON.
So the real ajax call should be:
$.ajax({
type: 'POST',
data: JSON.stringify({ datas: mapToObject(arr) }),
url : 'update.php',
success: function(responseText){
...
}
});
and on your server:
$data = file_get_contents("php://input");
print_r(json_decode($data, true));

How to get value in JavaScript array

I'm trying get a value inside a JavaScript array from the output of an AJAX request.
Ajax request:
$.ajax({
url: "ajax-test.php",
type: "POST",
data: "sku=800270",
dataType: "html"
}).done(function(resposta) {
console.log(resposta);
}
Ajax-Test.php:
$produto[] = array('sku' => $product->getSku(),
'name' => $product->getName());
var_dump($produto[0]);
Returns:
array(6) {
["sku"]=>
string(6) "000188"
["name"]=>
string(80) "Cuba Gastronômica Aço Inoxidável para Buffet GN 1/2×65mm (325x265mm) - 812-2"
}
I need to access the values inside the array, something like:
var sku = resposta["sku"]
In my tests if I try to print resposta["sku"] its giving me "undefined variable".
On php side you need to change var_dump($produto[0]); to echo json_encode($produto[0]). On JS side you need to change your request to dataType: "json", because it is not a html response. Then you can access the fields by the property names.
var sku = resposta.sku;
var name = resposta.name;
Your aproach is not wrong to, to access by a string:
var sku = resposta["sku"];
var name = resposta["name"];
So for conclusion, your php:
$produto[] = array(
'sku' => $product->getSku(),
'name' => $product->getName()
);
echo json_encode($produto[0]);
Your AJAX request:
$.ajax({
url: "ajax-test.php",
type: "POST",
data: "sku=800270",
dataType: "json"
}).done(function(resposta) {
var sku = resposta.sku;
var name = resposta.name;
console.log(sku, name);
}
Set a proper dataType for ajax object as dataType: "json"
Change your Ajax-Test.php file content as shown below(to send a proper json responce):
$produto[] = ['sku' => $product->getSku(), 'name' => $product->getName()];
echo json_encode($produto[0]);

Scraping JSON data from an AJAX request

I have a PHP function that echoes out JSON data and pagination links. The data looks exactly like this.
[{"name":"John Doe","favourite":"cupcakes"},{"name":"Jane Citizen","favourite":"Baked beans"}]
Previous
Next
To get these data, I would use jQuery.ajax() function. My code are as follow:-
function loadData(page){
$.ajax
({
type: "POST",
url: "http://sandbox.dev/favourite/test",
data: "page="+page,
success: function(msg)
{
$("#area").ajaxComplete(function(event, request, settings)
{
$("#area").html(msg);
});
}
});
}
Using jQuery, is there anyway I can scrape the data returned from the AJAX request and use the JSON data? Or is there a better way of doing this? I'm just experimenting and would like to paginate JSON data.
It's better to not invent your own formats (like adding HTML links after JSON) for such things. JSON is already capable of holding any structure you need. For example you may use the following form:
{
"data": [
{"name": "John Doe", "favourite": "cupcakes"},
{"name": "Jane Citizen", "favourite": "Baked beans"}
],
"pagination": {
"prev": "previous page URL",
"next": "next page URL"
}
}
On client-side it can be parsed very easily:
$.ajax({
url: "URL",
dataType:'json',
success: function(resp) {
// use resp.data and resp.pagination here
}
});
Instead of scraping the JSON data i'd suggest you to return pure JSON data. As per your use case I don't think its necessary to write the Previous and Next. I am guessing that the first object in your return url is for Previous and the next one is for Next. Simply return the below string...
[{"name":"John Doe","favourite":"cupcakes"},{"name":"Jane Citizen","favourite":"Baked beans"}]
and read it as under.
function loadData(page){
$.ajax
({
type: "POST",
url: "http://sandbox.dev/favourite/test",
dataType:'json',
success: function(msg)
{
var previous = msg[0]; //This will give u your previous object and
var next = msg[1]; //this will give you your next object
//You can use prev and next here.
//$("#area").ajaxComplete(function(event, request, settings)
//{
// $("#area").html(msg);
//});
}
});
}
This way return only that data that's going to change not the entire html.
put a dataType to your ajax request to receive a json object or you will receive a string.
if you put "previous" and "next" in your json..that will be invalid.
function loadData(page){
$.ajax({
type: "POST",
url: "http://sandbox.dev/favourite/test",
data: {'page':page},
dataType:'json',
success: function(msg){
if(typeof (msg) == 'object'){
// do something...
}else{
alert('invalid json');
}
},
complete:function(){
//do something
}
});
}
and .. in your php file, put a header
header("Content-type:application/json");
// print your json..
To see your json object... use console.log , like this:
// your ajax....
success:(msg){
if( window.console ) console.dir( typeof(msg), msg);
}
Change your json to something like this: (Use jsonlint to validate it - http://jsonlint.com/)
{
"paginate": {
"previous": "http...previsouslink",
"next": "http...nextlink"
},
"data": [
{
"name": "JohnDoe",
"favourite": "cupcakes"
},
{
"name": "JaneCitizen",
"favourite": "Bakedbeans"
}
]
}
You can try this :-
var jsObject = JSON.parse(your_data);
data = JSON.parse(gvalues);
var result = data.key;
var result1 = data.values[0];

Send array with ajax request to php

I created array like this ["9", "ques_5", "19", "ques_4"]. Now I want to send it from JS to PHP but I'm not getting proper results. My JS code is:
$(".button").click(function(e) {
e.preventDefault();
$.ajax({
type : 'post',
cache : false,
url : 'test/result.php',
data : {result : stuff},
success: function(resp) {
alert(resp);
}
});
});
In the above code stuff is an array which contains records. How can I send this array with above code and then in PHP I want to process this array like ques_5 is the key and 9 become the value for that key.
You can pass the data to the PHP script as a JSON object. Assume your JSON object is like:
var stuff ={'key1':'value1','key2':'value2'};
You can pass this object to the php code in two ways:
1. Pass the object as a string:
AJAX call:
$.ajax({
type : 'POST',
url : 'result.php',
data : {result:JSON.stringify(stuff)},
success : function(response) {
alert(response);
}
});
You can handle the data passed to the result.php as :
$data = $_POST["result"];
$data = json_decode("$data", true);
//just echo an item in the array
echo "key1 : ".$data["key1"];
2. Pass the object directly:
AJAX call:
$.ajax({
type : 'POST',
url : 'result.php',
data : stuff,
success : function(response) {
alert(response);
}
});
Handle the data directly in result.php from $_POST array as :
//just echo an item in the array
echo "key1 : ".$_POST["key1"];
Here I suggest the second method. But you should try both :-)
If you want to send key value pairs, which is what I am seeing, it would be better to use a PHP JSON library (like this one... http://php.net/manual/en/book.json.php)
Then you can send actual key value pairs, using JSON format like...
{"ques_5" : "19", "ques_4": "19"}
Try this
var array = ["9", "ques_5", "19", "ques_4"];
console.log(array.join(","));
above code will output string with comma separated like 9,ques_5,19,ques_4then paste it to ajax call.
And then in php explode that string.
Other possible solutions.
First
var obj = { 'item1': 'value1', 'item2': 'value2' };
$.ajax(
{
type: 'post',
cache: false ,
url: 'test/result.php',
data: { result : JSON.stringify(obj) },
success: function(resp)
{
alert(resp);
}
});
Second
var a = $.JSON.encode(obj);
$.ajax(
{
type: 'post',
cache: false ,
url: 'test/result.php',
data: { result : a },
success: function(resp)
{
alert(resp);
}
});
In PHP File
<?php
$json = $_POST["data"]
var_dump(json_decode($json));
?>
You can send the array in json format to the php and then use json_decode function to get back the array like
In ajax call you have to send json for that you need to first make array of the values so that you get it in right form
so that you json look like {"ques_5":"9","ques_4":19}
and use in ajax call
data: JSON.stringify(`your created json`),
contentType: "application/json; charset=utf-8",
dataType: "json",
IN PHP it look like
<?php
$json = '{"a":1,"b":2,"c":3,"d":4,"e":5}';
var_dump(json_decode($json));
?>
I would like to share a complete example that works for me in order to avoid making each JavaScript function for each PHP function
// on the HTML side a simple JavaScript call from a link
<a href="javascript:CargaZona('democonllamada', 'tituloprin', {'key1':'value1','key2':'value2'})" >test</a>
<div id='tituloprin' >php function response here!</div>
// on JavaScript side
function CargaZona(fc, div, params) {
var destino = "#" + div;
var request = $.ajax({
url : "inc/phpfunc.php",
type : "POST",
data : {
fc : fc,
params : JSON.stringify(params)
},
dataType : "html"
});
request.done(function (msg) {
$(destino).html(msg);
});
request.fail(function (jqXHR, textStatus) {
alert("Request failed: " + textStatus);
});
}
// on phpfunc.php page
<?php
$params = "{'key1':'value1','key2':'value2'}";
$fc = 'def';
if (isset($_POST['fc'])) { $fc = $_POST['fc']; }
if (isset($_POST['params'])) { $params = $_POST['params']; }
switch ($fc) {
default:
call_user_func($fc,$params);
}
function democonllamada($params) {
$params = json_decode("$params", true);
echo "ok llegaron".$params['key1'];
}
?>

Categories