I have an array of arrays of strings saved in a database column as a varchar:
[["ben"],["john","mike"],["ben"]]
I want to parse the data back into an array of arrays, so I can show the data on the screen. While attempting to do this, I ran into an awkward and annoying problem:
Here's the JSON response that is generated on the server and sent back to the client:
var response = "[{\"Names\":\""+ rows[i].Names + "\"}]";
res.send(response);
Here's the client code I wrote to parse the data:
jQuery.ajax({
type: "GET",
url: ...,
dataType: 'json',
contentType: "application/json; charset=utf-8"
}).done(function(data) {
jQuery.each(JSON.parse(data), function(i, parsedData) {
var names = JSON.parse(parsedData.Names);
var labels = "";
for (var n = 0; n < names.length; n++) {
var label = "<label>" + names[n] + "</label>";
labels = labels + label;
}
console.log(labels);
});
});
This is the error i'm getting:
Here's the JSON validation:
How can I solve this?
There is a simple rule:
Never use string tools to create or modify JSON. No string concatenation (+), no string replace and God forbid no regex.
The only way to produce JSON is to use a JSON serializer on a data structure. And the only way to manipulate JSON is to parse it, modify the data structure, and then serialize it again. JSON itself is to be treated as a constant, for all intents and purposes.
Your server code violates that rule. Change it like this:
var responseData = [{
Names: rows[i].Names
}];
var response = JSON.stringify(responseData);
In the above, responseData is a data structure. You are free to modify it. response is derived from that. You are not free to modify it, the only thing you can do with response is to write it to the client.
Note that rows[i].Names might be JSON itself, so you end up with a double-encoded value in your response.
Provided the server sends the Content-Type: application/json header, the client can use this:
jQuery.get("...").done(function(data) {
// data is already parsed here, you don't need to parse it
jQuery.each(data, function(i, item) {
// item.Names is not yet (!) parsed here, so we need to parse it
var names = JSON.parse(item.Names);
var labels = names.map(function (name) {
return $("<label>", {text: name});
}
console.log( labels );
});
});
If you don't want to call JSON.parse() on the client, you have to call it on the server:
var responseData = [{
Names: JSON.parse(rows[i].Names)
}];
var response = JSON.stringify(responseData);
Related
I'm trying to send object array to node.
If i'm sending it without stringify, i'm getting an array with the same length that i sent, but empty (["", ""]);
if i send it with JSON.stringify , this it the result:
{'[{"itemNumber":"13544","currentShelf":"1A1","amount":"1","newShelf":"","actionType":"in","whareHouse":"Main"},{"itemNumber":"13544","currentShelf":"1B1","amount":"1","newShelf":"","actionType":"in", "whareHouse":"Main"}]': '' }
This is how i'm sending it:
for (var i=1; i<=m; i++){
itemIdTemp= document.getElementById("itemIdShell"+i).value;
shellTemp= document.getElementById("id_shell"+i).value.toUpperCase();
newShellTemp= document.getElementById("id_shell_new"+i).value.toUpperCase();
shellAmountTemp = document.getElementById("amountShell"+i).value;
itemAmount=0;
let itemData={
itemNumber:itemIdTemp,
currentShelf:shellTemp,
amount:shellAmountTemp,
newShell:newShellTemp,
actionType:direction,
whareHouse:"Main",
};
console.log(itemData);
itemsObject.push(itemData);
}
console.log(itemsObject);
$.post('/itemShell/updateMulti',
JSON.stringify(itemsObject),
function(data){
console.log(data);
});
The object contain a string of the array and i can't get it.
I tried Json.Parse(), it won't work in this case.
any suggestions?
Have a look at this example code
const jsObjectArray = [
{name: "Homer", age:56 },
{name: "Marge", age:50 },
];
const buf = JSON.stringify(jsObjectArray);
console.log("Stringified object: "+buf);
//
// Now convert it back to an object
//
const newObject = JSON.parse(buf);
console.log("Reconstituted object: "+newObject);
It's in this codepen too:
https://codepen.io/mikkel/pen/KRayye
I found the problem.
It must be declare as JSON type when post to Node, so u need to use ajax:
$.ajax({
url: '/itemShell/updateMulti',
type:"POST",
data:JSON.stringify(dataTosend),
contentType:"application/json; charset=utf-8",
dataType:"json",
success: function(){}
}
and i also change it to object type like this:
dataToSend={dataArr:itemsObject}
So in node it's appearing as array
My Guy work a little bit on the string before sending it
First get the string the stringify is returning
var json_string = JSON.stringify(itemsObject);
var string = json_string.replace("'", "\'");
string = '{\'[{"itemNumber":"13544","currentShelf":"1A1","amount":"1",
"newShelf":"","actionType":"in","whareHouse":"Main"},
{"itemNumber":"13544","currentShelf":"1B1","amount":"1",
"newShelf":"","actionType":"in", "whareHouse":"Main"}]\': \'\' }';
first_str = string.split("': "); // remove the last useless chars
second = first_str[0].substring(2, first_str[0].length); // remove the first two chars
$.post('/itemShell/updateMulti', second,
function(data){
console.log(data);
});
the second should have the correct string.
GOODLUCK
I have a below set of code to get the table data in an array and pass the same to servlet through ajax call. But i am getting null. Please someone help me on what my mistake / how to get the required data since i am new to this servlet and web app. So far i tried with some examples given in SO. but i am clueless to get my expected data.
var myTableArray = [];
$("table#itemtable tr").each(function() {
var arrayOfThisRow = [];
var tableData = $(this).find('td');
if (tableData.length > 0) {
tableData.each(function() { arrayOfThisRow.push($(this).text()); });
myTableArray.push(arrayOfThisRow);
}
});
alert(myTableArray);
$.ajax({
url:"insertmasteritem",
type:"POST",
dataType:'json',
data: {json:myTableArray},
success:function(data){
// codes....
},
});
Servlet code
String[] myJsonData = request.getParameterValues("json[]");
System.out.println("myJsonData.length"+myJsonData.length);
for (int i = 0; i < myJsonData.length; i++) {
String[] innerArray=myJsonData[i].split(",");
System.out.println(myJsonData[i]);
}
Send your Json data like this
$.ajax({
url:"insertmasteritem",
type:"POST",
dataType:'json',
data:myTableArray,
success:function(data){
// codes....
},
});
and In Servlet Class
JSONObject jsonObj= new JSONObject(request.getParameter("myTableArray"));
Iterator it = jsonObj.keys();
while(it.hasNext())
{
String jsonKey = (String)it.next();
String jsonValue = jsonObj.getString(jsonKey);
System.out.println(jsonKey + " --> " + jsonValue );
}
Well, you need to send a properly formatted JSON object (as a string) to the servlet. Possibly the easiest way to do this is to create some javascript objects and fill an array with these objects. The array data should then be
converted to a JSON string (using JSON.stringify). I'm going to hardcode object values (but you will get them from your table)
Javascript code
function generateJson(){
var myObjArr = [];
//you will typically have just one object (e.g. myObj, which you will fill in your ajax table loop
//myObj.v1 = v1_val;
//myObj.v2 = v2_val;
...
//myObjArr[i] = myObj; //
myObj1 = { "v1": "Orange", "v2": "ABC", "v3":10,"v4":"OK" };
myObj2 = { "v1": "Apple", "v2": "XYZ", "v3":25,"v4":"OK" };
myObjArr[0] = myObj1;
myObjArr[1] = myObj2;
var jsonObjStr = JSON.stringify(myObjArr);
//you can now use jsonObjStr to send your data to the servlet
// document.getElementById("json").innerHTML = jsonObjStr;//this is just added for testing purposes
}
The generated JSON
[{"v1":"Orange","v2":"ABC","v3":10,"v4":"OK"},{"v1":"Apple","v2":"XYZ","v3":25,"v4":"OK"}]
As you can see, the json string starts with a [ (which denotes an array). You may have to change this to start with a { (and with a } ) depending on how your JSON parser works ({} denote an object).
For the servlet part, it depends on the actual JSON parser you're using. Try to use some of the suggestions provided by others. I can provide some code using Jackson though, but you will have to add the Jackson library to your classpath.
why you are getting parameter value as JSON[]
String[] myJsonData = request.getParameterValues("json[]");
Let's say I already have a JSON string; perhaps I got it from the server.
data = '{"a": 1, "b": 2}'
I want to use postMessage or some other API which requires a JSON string and send it the information in the form
{ action: 'save', data }
Of course I could do
postMessage(JSON.stringify({ action: 'save', data: JSON.parse(data) });
but this ends up arsing the data and then immediately restringifying it as part of the stringified object being send to postMessage.
Is there any clean way to take advantage of the fact that I already have the stringified version of part of the data to be sent? I am concerned about this because actually data could be 100K or more in length and parsing it and stringifying it is not free.
Note: I know I could send the JSON string for data as is and have the receiving side parse it, but I cannot change the semantics of the receiving side.
Note 2: Of course I could also engage in various ways of building the JSON myself, such as
'{ "action": "save", "data": ' + data + '}'
but would prefer to avoid that.
You can try something like this:
var data = {
"a":"test1",
"b":"test2",
"c":{
"c1":"test3.1",
"c2":"test3.2"
}
}
var object = {};
object["action"] = "save";
object["data"] = data;
console.log(object);
I asked myself the same question and was pointed to here.
There are different solutions to this. I setup a little jsperf test.
Most promising aproach (if you don't need to have the thing nested) is removing the end and adding the stringified json:
var stringifiedObject = JSON.stringify({
some: 'random',
obj: 'propterties'
});
var res = JSON.stringify({
outer: 'object'
});
res = res.substring(0, res.length-1) + ', "alreadyString":' + stringifiedObject + '}';
I am receiving after an ajax call the following as response using in php json_encode:
"['2013-02-24', 0]", "['2013-02-25', 0]", "['2013-02-26', 1]", "['2013-02-27', 6]", "['2013-02-28', 6]", "['2013-03-01', 3]", ...
How can I make in JavaScript from this an array of arrays? Is this even possible? I mean, I've tried with jQuery makeArray or with parseJSON with no success. What is the most preferred method?
Edit:
function submitForm(t) {
$.ajax({type:'GET', url: 'charts.php', data:$(page_id).serialize(), success:
function(response) {
var myFanRemovesData = new Array(response);
var myChart = new JSChart(chart_id, 'line');
myChart.setDataArray(myFanRemovesData);
I have to use the array of arrays to set myFanRemovesData with it
1) strip out the double-quotes ("):
var json = json.replace(/"/g, '');
2) wrap the whole thing in square brackets:
json = "[" + json + "]";
3) replace the single-quotes with double-quotes (because the singles won't parse):
json = json.replace(/'/g, '"');
4) parse the json string:
var arrays = JSON.parse(json);
Here is a working example. It will alert the first date in the first array. (note: the data is pulled from the DIV to simulate the AJAX call and to avoid me having to mess around with escaping quote characters)
Try:
var response = ["['2013-02-24', 0]", "['2013-02-25', 0]", "['2013-02-26', 1]"];
for (var i = 0; i < response.length; i++) {
var cleaned = response[i].replace(/'/g, "\"");
response[i] = $.parseJSON(cleaned);
}
DEMO: http://jsfiddle.net/hu3Eu/
After this code, the response array will contain arrays, made out of the original strings.
Just example.. because you haven't provide us with any code...
$.ajax({
type: "POST",
url: "some.php",
data: { name: "John", location: "Boston" },
dataType: 'json',
}).done(function( responde ) {
$.each(responde, function(i, v){
alert(v.0 + ' --- ' + v.1);
});
});
If you receive and expecting json you directly can use it as array/object :)
If its array you have to make a each loop so you can access each value..
I am trying to update a jqplot chart dynamically with Ajax requests.
My server is returning a string represtation of the data as such:
"[['Juice',30],['Milk',30],['Water',30]]"
However I need to convert this string into an array of arrays.
Is this the correct approach to update the data and if so what is the best way to convert the string.
$.ajax({
url:'http://localhost',
success:function(plotData){
var data = plotData.split(",");
if(plot){
plot.series[0].data = data;
plot.redraw();
}
},
fail:function(error){
alert('error:'+error);
}
});
This code will convert into a one dimentional array:
0: "[['Helpdesk'"
1: "30]"
2: "['Users'"
3: "30]"
4: "['Auto Generated'"
5: "30]]"
You can use eval("var x= " + plotData) as an alternate solution. There are few dangers in using eval, please go through it before using it.
for convertiong a string u possibly could use this function
var plotData = "[['Juice',30],['Milk',30],['Water',30]]";
function strToArr(str) {
//pattern that checks for '[', ']'
var patt=/[\[\]]/gi;
//we replace the pattern with '' symbol
var tmp = str.replace(patt,'').split(',');
var result = []
for (var i = 0; i < tmp.length; i+=2) {
//now all data is in one array, we have to putt in pairs
result[i] = [ tmp[i], tmp[i+1] ]
}
return result;
}
console.log( strToArr(plotData) );
Format your data correctly
It looks like the response you're getting from the server is supposed to be JSON. But, it isn't valid json, and as such is represented as a string.
The change required is very trivial, This is invalid json:
[['Juice',30],['Milk',30],['Water',30]]
This is valid json:
[["Juice",30],["Milk",30],["Water",30]]
The only difference is the quotes. Changing the response string, may (depending on what you're doing server side) correct things immediately such that plotData is already an array of 3 arrays.
Return the right content type
If you are not already serving the response with correct http headers - ensure the response is served as application/json, this of course is in addition to serving a valid JSON string.
Force interpretation as json
To force jQuery to attempt to parse the response as json - you can set dataType explicitly:
$.ajax({
...
dataType: 'JSON'
...
});
I can't remember how strict this is that may work with no server side modifications.
Use JSON.parse
Alternatively, if you just want to handle the string as-is; you could just use JSON.parse:
input = "[['Juice',30],['Milk',30],['Water',30]]";
jsonString = input.replace(/'/g, '"'); // correct quotes as per point 1
result = JSON.parse(jsonString);
result would then be an array containing 3 arrays.