JSON encode array parse correctly via Javascript - javascript

EXPLANATION
So from PHP to JavaScript encoded JSON array is sent in following:
$qa = array('question' => $question, 'a1' => $answer1, 'a2' => $answer2, 'a3' => $answer3);
echo json_encode($qa, JSON_UNESCAPED_UNICODE);
In JavaScript when I'm using like this (take a look at drawOutput):
function getSuccessOutput() {
getRequest(
't.php', // demo-only URL
drawOutput,
drawError
);
return false;
}
function drawOutput(responseText) {
var container = document.getElementById('output');
container.innerHTML = responseText;
}
function getRequest(url, success, error) {
var req = false;
try{
// most browsers
req = new XMLHttpRequest();
} catch (e){
// IE
try{
req = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
// try an older version
try{
req = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e){
return false;
}
}
}
if (!req) return false;
if (typeof success != 'function') success = function () {};
if (typeof error!= 'function') error = function () {};
req.onreadystatechange = function(){
if(req .readyState == 4){
return req.status === 200 ?
success(req.responseText) : error(req.status)
;
}
}
req.open("GET", url, true);
req.send(null);
return req;
}
I got following output:
{"question":"This is my question?","a1":"answer1","a2":"answer2","a3":"answer3"}
DESIRED RESULTS
I need extract each value from this array and assign to variables, example:
var myQuestion = "This is my question?";
var answ1 = "answer1";
var answ2 = "answer2";
var answ3 = "answer3";
WHAT I'VE TRIED
function drawOutput(responseText) {
var container = document.getElementById('output');
container.innerHTML = responseText;
// OUTPUT: {"question":"This is my question?","a1":"answer1","a2":"answer2","a3":"answer3"}
container.innerHTML = responseText[0];
// OUTPUT: <
container.innerHTML = responseText[a1];
// OUTPUT: nothing (blank)
}
Also I've tried:
function drawOutput(responseText) {
$.getJSON("t.php", function(responseText){
var container = document.getElementById('output');
var theObject = JSON.parse(responseText);
container.innerHTML = theObject[a1];
});
}
// OUTPUT: nothing (blank)
Also I've tried to use var theObject = JSON.parse(JSON.stringify(responseText)); instead of var theObject = JSON.parse(responseText); in this case output: undefined
If I'm using in following:
function drawOutput(responseText) {
var container = document.getElementById('output');
var theObject = JSON.parse(responseText);
container.innerHTML = theObject[a1];
}
// Output: nothing (blank)
But I got an error in browser's console: SCRIPT1014: Invalid character
I've read many similar issues, but nothing helped in my case. Have you any ideas, how could I solve It?
UPDATE
That's what I'm trying now and have nothing as output (blank):
function drawOutput(responseText) {
$.getJSON("t.php", function(responseText){
var question = theObject.question; // Get the question
var a1 = theObject.a1; // Get the answers
var a2 = theObject.a2;
var a3 = theObject.a3;
var container = document.getElementById('output');
container.innerHTML = a1;
alert(a1);
});
}

Parsing it is correct. If you get the text via XMLHttpRequest, you'll need to use JSON.parse on responseText. If you use jQuery's $.getJSON, it will do it for you and give you the parsed result.
The problem is how you're trying to access the values from the result. In theObject[a1], you're trying to use a variable called a1, whose value will then be used as the name of the property to get. Instead, use theObject.a1 or theObject["a1"].
So here, where you're using getJSON and so it's already been parsed for you:
function drawOutput() {
$.getJSON("t.php", function(theObject){ // Note: Not `responseText`, a parsed object
var question = theObject.question; // Get the question
var a1 = theObject.a1; // Get the answers
var a2 = theObject.a2;
var a3 = theObject.a3;
// ...use them...
});
}
Side note: Instead of separate a1,a2, anda3` properties on the object you're returning, you might consider using an array.
$qa = array(
'question' => $question,
'answers' => array($answer1, $answer2, $answer3)
);
echo json_encode($qa);
then
function drawOutput() {
$.getJSON("t.php", function(theObject){
var question = theObject.question; // Get the question
var answers = theObject.answers; // Get the answers
// ...use question, and `answers[0]` through `answers[2]`, where
// you can get the number of answers from `answers.length`...
});
}

You can access object values with one of these method:
var responseText = '{"question":"This is my question?","a1":"answer1","a2":"answer2","a3":"answer3"} ';
var theObject = JSON.parse(responseText);
console.log(theObject['a1']); // a1 in string
console.log(theObject.a1); // Gives the same result

In PHP you need to json_encode your response :
$ServerResponse= json_encode($MyJSON);
In Javascript you need to JSON.parse the response you got from PHP :
var myJSONObject = JSON.parse(ServerResponse);
After that , you have a normal Object in your hands , and that is myJsonObject. You can access its properties either with the use of "dot" (Eg. myJsonObject.PROPERTY_NAME) or with brackets (Eg myJsonObject["PROPERTY_NAME"]).

Related

Creating & sending JSON from client to server, and expected result

I'm trying to parse user input from my webpage and store it in a JSON object using inline JavaScript, make a POST request to my Node.js server, and access the contents of the request.
In my example.html, I have a function which does the following:
var xhttp = new XMLHttpRequest();
dataToSubmit = [];
// find some inputs
for ( /* each row of input */ ) {
dataToSubmit.push({
'item': itemName,
'quantity': quantity,
'price': itemPrice
});
}
xhttp.open("POST", "http://localhost:8080/menu", true);
xhttp.setRequestHeader('Content-Type', 'application/json');
xhttp.send(JSON.stringify(dataToSubmit));
EDIT :
After the POST request, I have a dispatcher.js file that processes the requests:
function(request, response) {
var qs = require('querystring');
var requestBody = '';
request.on('data', function(data) { requestBody += data; });
request.on('end', function() {
var qs = require('querystring');
var passed_data = qs.parse(requestBody);
if(request.url === "/menu") {
var menu_handler = require("./menu.js");
menu_handler.processOrder(passed_data);
}
}
I'm exporting processOrder() from my menu.js. The issue is that on the server-side, I have to do the following in order to access the object:
processOrder: function(data) {
for (var a in data) { <-------------- Having to do this seems incorrect
// a is a string, inputs is the expected object
var inputs = JSON.parse(a);
}
}
My question is: is the way I'm creating the JSON object incorrect, or is the way I'm accessing it on the server-side incorrect? My expectation is that, on the server-side, I should be able to do something like this:
processOrder: function(data) {
var inputs = JSON.parse(data);
for (var input in inputs) {
// access to input.item, input.quantity, input.price
}
}
Make dataToSubmit an object:
dataToSubmit = {};
For each input row, add a uniquely keyed property to your dataToSubmit, and assign it an object:
dataToSubmit['keyName' + index] = {}
Assign this new object properties like:
dataToSubmit['keyName' + index]['item'] = itemName;
dataToSubmit['keyName' + index]['quantity'] = quantity;
dataToSubmit['keyName' + index]['price'] = itemPrice;
The cause of me not being able to access the dataToSubmit variable as a JSON object was that I was doing parsing at a previous layer before the data reached the processOrder function. The solution was to make the following changes in my dispatcher.js file (which processes the requestBody before it makes its eventual way to menu.js):
function(request, response) {
var qs = require('querystring');
var requestBody = '';
request.on('data', function(data) { requestBody += data; });
request.on('end', function() {
var qs = require('querystring');
var passed_data;
if(request.headers['content-type'] === 'application/json') { <--- parse JSON data
passed_data = JSON.parse(requestBody);
else {
passed_data = qs.parse(requestBody);
}
if(request.url === "/menu") {
var menu_handler = require("./menu.js");
menu_handler.processOrder(passed_data);
}
}
Furthermore, when creating the JSON object, the following needed to be done in order to access the data as a JSON object rather than as an array:
dataToSubmit = {'content': []};
dataToSubmit['content'].push(
{
'item': itemName,
'quantity': quantity,
'price': itemPrice
}
);

Can't check an empty JSON key: value pair

I've tried several answers posted in the site like:
How to check if JSON return is empty with jquery
And no one is working for me.
xhr.onload = function(){
detalles = xhr.responseText;
console.log("log : "+detalles);
....
}
Console output:
log : [0]
Firefox debugger network tab shows JSON 0: 0
Any help provided will be much appreciated.
EDIT - Adding some more code to extend the context
xhr.onload = function(){
detalles = xhr.responseText;
console.log(detalles);
if((!$.trim(detalles))||($.isEmptyObject(detalles))||(!detalles[0])){
console.log("ok");
$("#graficohist").html("No info available");
triggerLoader();
}
You can simply make a function to test in the object is empty
var myObj = {"key" : "value"};
checkEmptyJson = function(myObj){
var count = 0;
for(var key in myObj){
count++;
break;
}
if(count == 0){
return false; // object is empty
}else{
return true; // object is not empty
}
}
var result = checkEmptyJson(myObj);
console.log(result);
In your context we can use it as
hasDetallesData = checkEmptyJson(detalles); // true if Detalles has data
I suggest to try this
var obj = JSON.parse(text);
to convert your json to a javascript object, and then you can make a print it with
console.log(obj)
to see what you have inside the obj

Array value becomes null while passing from Ajax

I am making an ajax call in my javascript submit function. In this ajax call, I am passing an array(globalSelection) as data to the servlet. This array consists elements of function textSelection which is also pasted below.
globalSelection =[];
function submit() {
console.log("globalSelection start")
console.log(globalSelection)
console.log("globalSelection end")
$.ajax({
async : false,
type : "POST",
url : 'http://example.com:8080/myApp/DataServlet',
data: {globalSelection:globalSelection},
success : function(data) {
alert(data)
},
error : function(data, status, er) {
alert("error: " + data + " status: " + status + " er:" + er);
}
});
}
function textSelection(range, anchorNode, focusNode) {
this.range = range;
this.type = 3;
this.rCollection = [];
this.textContent = encodeURI(range.toString());
this.anchorNode = anchorNode;
this.focusNode = focusNode;
this.selectionId = getRandom();
this.yPOS = getYPOS();
this.getTagName = function(range) {
var el = range.startContainer.parentNode;
return el;
}
this.getTagIndex = function(el) {
var index = $(el.tagName).index(el);
return index;
}
this.simpleText = function(node, range) {
if (!node)
var entry = this.createEntry(this.anchorNode, this.range);
else
var entry = this.createEntry(node, range);
this.rCollection.push(entry);
this.highlight(this.rCollection[0].range);
this.crossIndexCalc();
textSelection._t_list.push(this);
pushto_G_FactualEntry(this);
}
this.compositeText = function() {
this.findSelectionDirection();
var flag = this.splitRanges(this.anchorNode, this.focusNode,
this.range.startOffset, this.range.endOffset);
if (flag == 0) {
for (j in this.rCollection) {
this.highlight(this.rCollection[j].range);
}
}
this.crossIndexCalc();
textSelection._t_list.push(this);
pushto_G_FactualEntry(this);
}
}
I am ading the screen of my browser console below, which prints the globalSelection(array).
In my servlet I am getting this array as follows
String[] arrays = request.getParameterValues("globalSelection[]");
System.out.println(arrays);
Here I am getting null value for arrays.
If I put globalSelection as follows in submit function for simple test to servlet, I am able to get the arrays.
var globalSelection = ["lynk_url", "jsonBody", "lynk_dummy1", "lynk_dummy2", "lynk_name", "lynk_desc", "lynk_flag"];
Why my actual globalSelection is shows null in servlet, what I am doing wrong here.
Try with :
String[] arrays = request.getParameterValues("globalSelection");
System.out.println(arrays);
Because the parameter submitted with name "globalSelection" only not "[]" symbol.
I see your problem and I have a simple solution.
I recommend in that case that you convert the array as a string in JS:
JSON.stringify(globalSelection)
and then reconstructing the object on the backend using some sort of library for JSON conversion like: https://code.google.com/archive/p/json-simple/
You could then do something like this:
JSONArray globalSelection = (JSONArray) new JSONParser().parse(request.getParameter("globalSelection"));
Iterator i = globalSelection.iterator();
while (i.hasNext()) {
JSONObject selection = (JSONObject) i.next();
String type = (String)selection.get("type");
System.out.println(type);
}
This will parse your array and print the selection type. Try it, hope it helps.

Return result from a javascript callback (node.js)

I know this question have been asked many times, but I can't make it work.
Here is my situation. I had a string called data, and I want to unshorten all the link inside that string.
Code:
var Bypasser = require('node-bypasser');
var URI = require('urijs');
var data = 'multiple urls : http://example.com/foo http://example.com/bar';
var result = URI.withinString(data, function(url) {
var unshortenedUrl = null;
var w = new Bypasser(url);
w.decrypt(function(err, res) {
// How can I return res ?
unshortenedUrl = res;
});
// I know the w.descrypt function is a asynchronous function
// so unshortenedUrl = null
return unshortenedUrl;
});
Let's me walk you through the code.
URI.withinString will match all the URLs in data, manipulate it and return the result.
You can view an example from URI.js docs
What I want to with these URLs is to unshorten all of them using node-passer.
This is from node-bypasser document:
var Bypasser = require('node-bypasser');
var w = new Bypasser('http://example.com/shortlink');
w.decrypt(function(err, result) {
console.log('Decrypted: ' + result);
});
This is the result that I want multiple urls : http://example.com/foo_processed http://example.com/bar_processed
I created a notebook at tonicdev.com
Solution
var getUrlRegEx = new RegExp(
"(^|[ \t\r\n])((ftp|http|https|gopher|mailto|news|nntp|telnet|wais|file|prospero|aim|webcal):(([A-Za-z0-9$_.+!*(),;/?:#&~=-])|%[A-Fa-f0-9]{2}){2,}(#([a-zA-Z0-9][a-zA-Z0-9$_.+!*(),;/?:#&~=%-]*))?([A-Za-z0-9$_+!*();/?:~-]))"
, "g"
);
var urls = data.match(getUrlRegEx);
async.forEachLimit(urls, 5, function (url, callback) {
let w = new Bypasser(url);
w.decrypt(function (err, res) {
if (err == null && res != undefined) {
data = data.replace(url, res);
callback();
}
});
}, function(err) {
res.send(data);
});
You don't really understand what callback is. The callback serves to allow asynchronous code to run without Javascript waiting for it. If you were less lazy and added some debug in your code:
console.log("Started parsing");
var result = URI.withinString(data, function(url) {
console.log("URL parsed (or whatever)");
var unshortenedUrl = null;
var w = new Bypasser(url);
w.decrypt(function(err, res) {
// How can I return res ?
unshortenedUrl = res;
});
// I know the w.descrypt function is a asynchronous function
// so unshortenedUrl = null
return unshortenedUrl;
});
console.log("Call to library over");
You would (most likely) see messages in this order:
Started parsing
Call to library over
URL parsed (or whatever)
The answer: Callback is not guaranteed to run before any code you execute after assigning it. You can't put data in your result variable because the data might not be fetched yet.

JSON parsed object and wild card

I have a function that is supposed to check old data against data. I am parsing data and oldData to get a JSON object respectively as dbData and formData are simply strings containing ID's and values for the HTMML form. The purpuse of the function is to check if the user has made any textchanges some textareas in the HTML form. I want to do this by checking the ID for each textarea and then check if the value in formData and Data are the same. In that case no change has been made and the function will return true.
The data string im parsing looks something like this:
"[{\"texts\":[{\"default\":true,\"bread-texts\":false,\"textarea1\":\"Banana\",\"textarea2\":\"Kiwi\",\"textarea3\":\Apple \",\"textarea4\":\"coffe\",\"textarea5\":\"Tea\",\"signature\":true,\"profile\":\"header\",\"fontsize\":\"26\",\"fontsize-headers\":\"10.5\",\"fontcolor\":\"#0000\",\"textfont\":\"header-large\",\"textsub1\":\"Bold\",\"font\":\"ICA%20Text\",\"textsub\":\"Regular\",\"textsize\":\"20\",\"textsize-signature\":\"9.5\",\"textsizesmall\":\"5.5\",\"textsizesmall-placer\":\"2.75\",\"vers-placer\":\"false\",\"text-colored\":\"%23000000\",\"s-all-customers\":true,\"new-customers\":true,\"undefined\":\"\"}]}]"
So for example, i have to check the ID for "textarea1" in dbData and formData and then check if the value is the same. Can this be done using wildcard or is there a better way to archive this?
function CheckValues() {
var isChanged = false;
var formData = $.parseJSON(data);
var dbData = $.parseJSON(oldData);
if(formData !== dbData) {
var isChanged = true;
}
return isChanged;
}
The code shown below works in IE9+, Chrome, FireFox but other
browsers yet to test. The example shows two different values, data and
OldData - data contains "Tea" where as OldData contains "OldTea" so
isChanged flag is true.
function CheckValues() {
var data = "{\"disable\":false,\"textarea1
\":\"Banana\",\"textarea2\":\"Kiwi\",\"textarea3
\":\"Milk\",\"textarea4\":\"Coffe\",\"textarea5\":\"Tea\"}";
var oldData = "{\"disable\":false,\"textarea1
\":\"Banana\",\"textarea2\":\"Kiwi\",\"textarea3
\":\"Milk\",\"textarea4\":\"Coffe\",\"textarea5\":\"OldTea\"}";
var formData = JSON.parse(data);
var dbData = JSON.parse(oldData);
var oFormData = Object.keys(formData);
var oDbData = Object.keys(dbData);
var isChanged = false;
if (oFormData.length === oDbData.length)
{
for (var i = 0; i < oFormData.length; i++) {
var propName = oFormData[i];
if (typeof (dbData[propName]) === "undefined") {
isChanged = true;
break;
}
else {
if (formData[propName] !== dbData[propName]) {
isChanged = true;
break;
}
}
}
}
}

Categories