How to access elements of JSON array in javascript? - java

I'm currently creating an ArrayList in Java, then running the .toJson function from Google-gson on it:
public String statusesToJson(ArrayList<String> statuses){
Gson gson = new Gson();
return gson.toJson(statuses);
}
Which results in the JSON:
[ "u", "u", "u", "u" ]
Then in JSP I'm passing it into JavaScript:
<script language="JavaScript" type="text/javascript">CheckStatus.loaded('<%=model.getPageId() %>', '<%=request.getContextPath() %>', '<%=model.arrayListToJson(model.getStatuses()) %>');</script>
Then in the JavaScript I'm parsing it to a JSON array:
CheckStatus.statuses = JSON.parse(statuses);
alert(CheckStatus.statuses);
This then results in the following output:
u, u, u, u
The problem is that the following doesn't work and causes my page to not load:
alert(CheckStatus.statuses[0]);
What's wrong with this?
EDIT:
Loaded Function:
loaded : function(guid, context, statuses) {
CheckStatus.guid = guid;
CheckStatus.context = context;
CheckStatus.statuses = JSON.parse(statuses);
alert(CheckStatus.statuses[0]);
if(CheckStatus.init == null){
submitForm('checkStatusForm', CheckStatus.guid);
CheckStatus.init = true;
}
setupForm('checkStatusForm', function(){CheckStatus.validStatus();});
//CheckStatus.setImages();
applyCSS3('Check_Status');
}
Valid Status Function:
validStatus : function(){
CheckStatus.params = $('#checkStatusForm').serializeObject();
if(document.getElementById('regionID').value != "" && document.getElementById('regionAction').value != ""){
submitForm('checkStatusForm', CheckStatus.guid);
}else{
error("Cannot Commit", "You must select an action before attempting to commit.");
}
},
Setup Form Function:
/**
* Sets up the form to submit when the user presses enter inside an input
* element. Also calls the callback when the form is submitted, does not
* actually submit the form.
*
* #param id The id of the form.
* #param callback The callback to call.
* #return Nothing.
*/
function setupForm(id, callback) {
$('#' + id + ' input').keydown(function(e) {
if (e.keyCode === 13) {
$(this).parents('form').submit();
e.preventDefault();
}
});
$('#' + id).submit(function(e) {
e.preventDefault();
callback();
});
}
Submit Form Function:
/**
* Serializes and submits a form.
*
* #param id
* The id of the form to submit.
* #param guid
* The guid of the page the form is on to pass to the server.
* #return nothing.
*/
function submitForm(id, guid) {
var subTabId = $('#' + id).closest('#tabs > div > div').attr(
'id'), tabId = $('#' + id).closest('#tabs > div')
.attr('id'), data = $('#' + id).serializeArray();
data.push( {
name : "framework-guid",
value : guid
});
$.ajax( {
type : 'POST',
cache : 'false',
url : '/pasdash-web/' + tr("_", "", tabId.toLowerCase()) + '/' + tr("_", "", subTabId)
+ '.jsp',
data : data,
success : function(html) {
$('#' + subTabId).html(html);
resourceChanged(tabId, subTabId,
$('#' + id + ' input[name="framework_command"]')[0].value,
guid);
},
error : function(jqXHR, textStatus, errorThrown) {
error('Ajax Error', textStatus);
}
});
return false;
}

You don't need to wrap your JSON with strings, that will just force you to have to reparse it. I would try removing those quotes and not calling JSON.parse
loaded : function(guid, context, statuses) {
CheckStatus.guid = guid;
CheckStatus.context = context;
// Here's the change
CheckStatus.statuses = statuses;
alert(CheckStatus.statuses[0]);
And change your HTML to be
<script type="text/javascript">
CheckStatus.loaded('<%=model.getPageId() %>',
'<%=request.getContextPath() %>',
// the following line should output something like
// ["a", "b"]
// which is perfectly valid JavaScript
<%=model.arrayListToJson(model.getStatuses()) %>);
</script>

You should be able to write:
CheckStatus.loaded('<%=model.getPageId() %>', '<%=request.getContextPath() %>', <%=model.arrayListToJson(model.getStatuses()) %>);
without the quotes around the last argument. Then, that "loaded()" function will get the object directly and there'll be no need to call "JSON.parse()".

Check the type of the result of JSON.parse (). Seems to me that it is a string and not an array. Maybe a pair of quotes somewhere that should not be there?

Related

How to get json data from controller in jsp?

I want to populate my json data into d3 charts. But how to get json data from controller?
Here rootVO is json file and i am passing to jsp but i don't know how to collect it and use it in jsp?
Controller class
#RequestMapping("/sunburst")
public String sunburstChart(Model model)
{
model.addAttribute("jsonData", rootVO);
return "sunburstChart";
}
Another jsp file from where i am calling that method
$.ajax
({
url: "sunburst",
async: false,
success: function(data)
{
console.log(data);
$("#sunburstChart").append(data);
}
});
Here is my sunburstChart.jspin which i want json data
<!DOCTYPE html>
<head>
<title>Sunburst Tutorial (d3 v4), Part 3</title>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<style>
#import url('https://fonts.googleapis.com/css?family=Raleway');
body {
font-family: "Raleway", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
</style>
<body>
<svg></svg>
<label><input class="sizeSelect" type="radio" name="mode" value="size" checked /> Size</label>
<label><input class="sizeSelect" type="radio" name="mode" value="count" /> Count</label>
</body>
<script>
// Variables
var width = 500;
var height = 500;
var radius = Math.min(width, height) / 2;
var color = d3.scaleOrdinal(d3.schemeCategory20b);
var sizeIndicator = "size";
var colorIndicator = "sentiment";
// Size our <svg> element, add a <g> element, and move translate 0,0 to the center of the element.
var g = d3.select('svg')
.attr('width', width)
.attr('height', height)
.append('g')
.attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')');
// Create our sunburst data structure and size it.
var partition = d3.partition()
.size([2 * Math.PI, radius]);
// Get the data from our JSON file
d3.json(
$.ajax
({
type:"GET",
dataType : 'json',
url : '/sunburst',
success : function(response)
{
},
error: function() {
alert("asda");
}
});
, function(error, nodeData) {
if (error) throw error;
// Find the root node, calculate the node.value, and sort our nodes by node.value
var root = d3.hierarchy(nodeData)
.sum(function (d) { return d.size; })
.sort(function(a, b) { return b.value - a.value; });
// Calculate the size of each arc; save the initial angles for tweening.
partition(root);
arc = d3.arc()
.startAngle(function (d) { d.x0s = d.x0; return d.x0; })
.endAngle(function (d) { d.x1s = d.x1; return d.x1; })
.innerRadius(function (d) { return d.y0; })
.outerRadius(function (d) { return d.y1; });
// Add a <g> element for each node; create the slice variable since we'll refer to this selection many times
var slice = g.selectAll('g')
.data(root.descendants())
.enter().append('g').attr("class", "node");
// Append <path> elements and draw lines based on the arc calculations. Last, color the lines and the slices.
slice.append('path').attr("display", function (d) { return d.depth ? null : "none"; })
.attr("d", arc)
.style('stroke', '#fff')
.style("fill", function (d) { return color((d.children ? d : d.parent).data.name); });
// Populate the <text> elements with our data-driven titles.
slice.append("text")
.attr("transform", function(d) {
return "translate(" + arc.centroid(d) + ")rotate(" + computeTextRotation(d) + ")"; })
.attr("dx", "-20")
.attr("dy", ".5em")
.text(function(d) { return d.parent ? d.data.name : "" });
// Redraw the Sunburst Based on User Input
d3.selectAll(".sizeSelect").on("click", function(d,i) {
// Determine how to size the slices.
if (this.value === "size") {
root.sum(function (d) { return d.size; });
} else {
root.count();
}
partition(root);
slice.selectAll("path").transition().duration(750).attrTween("d", arcTweenPath);
slice.selectAll("text").transition().duration(750).attrTween("transform", arcTweenText);
});
});
/**
* When switching data: interpolate the arcs in data space.
* #param {Node} a
* #param {Number} i
* #return {Number}
*/
function arcTweenPath(a, i) {
var oi = d3.interpolate({ x0: a.x0s, x1: a.x1s }, a);
function tween(t) {
var b = oi(t);
a.x0s = b.x0;
a.x1s = b.x1;
return arc(b);
}
return tween;
}
/**
* When switching data: interpolate the text centroids and rotation.
* #param {Node} a
* #param {Number} i
* #return {Number}
*/
function arcTweenText(a, i) {
var oi = d3.interpolate({ x0: a.x0s, x1: a.x1s }, a);
function tween(t) {
var b = oi(t);
return "translate(" + arc.centroid(b) + ")rotate(" + computeTextRotation(b) + ")";
}
return tween;
}
/**
* Calculate the correct distance to rotate each label based on its location in the sunburst.
* #param {Node} d
* #return {Number}
*/
function computeTextRotation(d) {
var angle = (d.x0 + d.x1) / Math.PI * 90;
// Avoid upside-down labels
return (angle < 120 || angle > 270) ? angle : angle + 180; // labels as rims
//return (angle < 180) ? angle - 90 : angle + 90; // labels as spokes
}
</script>
You can't send json-data the way you have shown and achieve what you want.
To do this you have can follow any one mentioned below:
read your json file, deserialize to a POJO and then send deserialized data from a separate controller-endpoint. Make sure you call your ajax method from client end on document ready state.
read your json file, deserialize to a POJO and then send with modelAttribute as you have done i.e model.addAttribute("jsonData", deseriazedData); and read from controller side by JS like: var yourJsonData=${jsonData}, parse to jsonData with JSON.parse(yourJsonData) and then use that for your chart.
But make sure, all events like page loading then generating chart from this data are happening one after another in desired order.
P.S.: search read json file and map to pojo if you find difficulties.
If you are unsure or need more help, then state your json file data structure and your specific problem. I will try to help

Making an AJAX POST on websocket message is causing timeout exceptions

So I have a program that basically allows two users two chat back and forth and do other things via websocket with javascript and java server endpoints. When one of the users presses a button I have a listener that fires off a message to the other user which invokes a function. During this function I want to be able to call an AJAX POST with JQuery to update my database but this is causing a java.util.concurrent.TimeoutException. Any idea why this occurs? I imagine it has something to do with the fact that the websocket connection doesn't stay open long enough for the ajax call to go through.
So I've done the research and I've seen that websocket and AJAX are not exactly something that should be mixed (I think). However I can't seem to figure out an alternative even to update my database. There is a lot of code for this so I will try and only post the important parts.
Here is the part of the code for when the button is pressed (it is an agree button so both users must have pressed it hence the '**' and '--' characters).
fAgree.addEventListener("click", function() {
// selects this button
if (aStr == "**" && (yStr == "**" || oStr == "**")) {
if (fStr == "--") {
fStr = "*-";
//redirect to another page
} else if (fStr == "-*") {
fStr = "**";
if(secondTransaction == false) {
var firstCoordUpload = document.getElementById("yourPos").innerHTML;
var secondCoordUpload = document.getElementById("othersPos").innerHTML;
var firstLatUpload = parseFloat(firstCoordUpload.split(",")[0]);
var firstLonUpload = parseFloat(firstCoordUpload.split(",")[1]);
$.ajax({
url: "../../309/T11/setSaleData/" + getURLParameter("saleID") + "/" + firstLatUpload + "/" + firstLonUpload + "/" + firstCoordUpload + "/" + secondCoordUpload + "/" + secondSeller,
type: "POST",
headers: {
"Authorization" : getCredentials(),
},
success: function (result) {
window.location.href = '../../frontEnd/profilePage/index.html?username='+ getUsername();
console.log(result);
},
error: function (dc, status, err) {
console.log(err);
console.log(status);
}
});
}
}
agreeBut.socket.send("a,f");
htmlChange(fStr, fStar);
}
});
Here is the part of the code that is called at the end of the code above (the agreeBut.socket.send()).
agreeBut.socket.onmessage = function(message) {
// check [0]: a for agree buttons,
// m for map,
// l of location buttons,
// t for trade
var mess = message.data.split(",");
if (mess[0] == "a") {
// second a shows the agree button was pressed, changes aStr
// accordingly and displays
if (mess[1] == "a") {
if (aStr == "--") {
aStr = "-*";
} else if (aStr == "*-") {
aStr = "**";
}
htmlChange(aStr, aStar);
// shows the final agree button has been pressed, changes fStr
// accordingly and displays
} else if (mess[1] == "f") {
if (fStr == "--") {
fStr = "-*";
//redirect
} else if (fStr == "*-") {
fStr = "**";
alert("on this");
if(secondTransaction == true) {
alert("doing it");
var firstCoordUpload = document.getElementById("yourPos").innerHTML;
var secondCoordUpload = document.getElementById("othersPos").innerHTML;
var firstLatUpload = parseFloat(firstCoordUpload.split(",")[0]);
var firstLonUpload = parseFloat(firstCoordUpload.split(",")[1]);
$.ajax({
url: "../../309/T11/setSaleData/" + getURLParameter("saleID") + "/" + firstLatUpload + "/" + firstLonUpload + "/" + firstCoordUpload + "/" + secondCoordUpload + "/" + secondSeller,
type: "POST",
headers: {
"Authorization" : getCredentials(),
},
success: function (result) {
console.log(result);
alert("Got it");
window.location.href = '../../frontEnd/profilePage/index.html?username='+ getUsername();
},
error: function (dc, status, err) {
console.log(err);
console.log(status);
}
});
}
//window.location.href = '../../frontEnd/profilePage/index.html?username='+ getUsername();
}
htmlChange(fStr, fStar);
}
}
};
It turns out I was getting this problem because of the timeout that was set on my java ServerEndpoint. In the class I used the setMaxIdleTimeout(0) function on the session variable to have no idle timeout. This seemed to solve my problem (however I feel like this is really just a workaround for poor websocket and ajax implementation on my end).

"arg 1 could not unmarshal" during JSON-RPC call

I have the unenviable task of editing a 2000 line javascript file inorder to maintain and add some new feature to a web app written in JSP, Json-RPC, jQuery and Java. I do not possess any deeper knowledge of jQuery and Json-RPC except basic Javascript knowledge and the original developer is not there anymore.
There is a JS function which accepts a few params, and calls a Json-RPC and here I am getting the error
arg 1 could not unmarshal
Can someone please tell me what this error means?
Here is my code
function distributeQuantityNew(pReportId, pDecimalPlaces, pRun) {
try {
alert('distributeQuantityNew: ' + pReportId + ', ' + pDecimalPlaces + ', ' + pRun);
var fieldValue = $("#distribution_quantity_" + pReportId).val();
if (fieldValue.length == 0) {
showErrorDialog(resourceBundleMap["error.no.distribution.quantity"]);
return;
} else {
$("#distribution_quantity_" + pReportId).val("");
}
var affectedRowIds = [];
var rows = $("#tableBody_" + pReportId + " tr:visible").has("input[type=text]").filter(function(index) {
var voucherType = this.cells[getVoucherColumnIndex()].innerHTML;
if ((voucherType == 'TRANSFER_CS') || (voucherType == 'PAYOUT_CS') || (voucherType == 'SOURCE_BON') || (voucherType == 'PAYOUT_BON')) {
return false;
}
affectedRowIds.push(parseInt(this.id.split("_")[3]));
return true;
}
);
var affectedReportRows = $.extend(true, {}, foreignReportMap[pReportId]);
$.each(affectedReportRows.map, function(i, row) {
if ($.inArray(row.partnerReportBillNr, affectedRowIds) == -1) {
delete affectedReportRows.map["row_" + row.partnerReportBillNr];
}
});
var report = getLoadedReportByRunId(pReportId);
var productType = report.partnerProductType;
SessionManager.extend();
var resultRows = jsonrpc.foreignReportObject.distributeQuantity(affectedReportRows, fieldValue, pDecimalPlaces, pRun);
alert('back after RPC');
$.each(resultRows.map, function(i, row) {
foreignReportMap[pReportId].map["row_" + row.partnerReportBillNr] = row;
updateForeignReportRow(row, true, productType);
});
updateSummaryRow(pReportId);
toggleApproveAllLink(pReportId);
sortForeignReportTable(pReportId, true);
} catch (e) {
handleError("Failed to distribute quantity: ", e);
}
}
I have peppered it with alerts so that I know whether RPC call was succesful, but I get the error arg 1 could not unmarshal before that from the catch block. Thanks for any hints
OK, got it solved. The first parameter to the remote function is expecting a list of Map<String, SomeBO>. SomeBO is a bean with several BigDecimals. I had another JS function which had set the values passed into the Map. This function was setting a BigNumber where I had a setter of String only. I wish the error I had gotten back from JSON unmarshaller was a bit more descriptive...Below is the code where I added .toString() to solve the issue
foreignReportMap[pReportId].map["row_" + pRowId].clientQuantity = clientQuantity.toString();
foreignReportMap[pReportId].map["row_" + pRowId].totalClientQuantity = totalClientQuantity.toString();

jQuery Select2 and Struts 2 JSON plugin

I'm trying to populate with Struts2 JSON and Select2 a select. Server is returning a JSON like this:
{"orphanets":[{"idDiagOrphanet":11509,"nomDiagOrphanet":"FACOMATOSIS CESIOFLAMMEA"},{"idDiagOrphanet":21782,"nomDiagOrphanet":"AUTOINFLAMMATION"}]}
How can I format/parse the result to make it work? I know it expects id and text fields, but cant get it working:
$("#selCodOrphanet").select2({
quietMillis: 300,
placeholder: "Buscar diag. Orphanet...",
minimumInputLength: 4,
ajax: {
url: '../json/getOrphanets',
dataType: 'json',
data: function (term, page) {
return {
term: term
};
},
results: function (data, page) {
return { results: data.orphanets };
},
id: function(item) {
return item.idDiagOrphanet;
},
formatResult: function(item) {
return "<div class='select2-user-result'>" + item.nomDiagOrphanet + "</div>";
}
}
});
I tried a bit searching but didn't found id: function(item) {
Anyways, here's a quick-fix
Consider the response as a normal string
replace idDiagOrphanet with id and nomDiagOrphanet with text and then return this string instead of return { results: data.orphanets };
Here's another way :
Modifying a JSON object by creating a New Field using existing Elements
var ornts= data.orphanets;
var new_obj ;
for(var i=0; i<data.orphanets.length; i++){
var person = persons[i];
new_obj.push({
id: ornts.idDiagOrphanet,
text: ornts.nomDiagOrphanet,
});
}
return new_obj;
Try
$("#selCodOrphanet").select2({
placeholder: "Buscar diag. Orphanet...",
minimumInputLength: 4,
ajax: {
url: '<s:url namespace="/json" action="getOrphanets"/>',
dataType: 'json',
quietMillis: 100,
data: function (term, page) {
return {
term: term
};
},
results: function (data, page) {
return { results: data.orphanets };
},
id: function(item) {
return item.idDiagOrphanet;
},
formatResult: function(item) {
return "<div class='select2-user-result'>" + item.nomDiagOrphanet + "</div>";
}
escapeMarkup: function (m) { return m; }
}
});
Added the qualified URL mapping to getOrphanets action with namespace /json. Corresponding configuration should be made. Don't escape markup since you are displaying HTML in results.

How to pass Object to controller using javascript

I am having one modelform
public class ABC
{
private String a;
private String b;
private Obj obj;
...getteres and setters.....
}
in my jsp my OnSubmit function is
function showMethod(rowid)
{
document.diamondSingleStoneLabForm.action = adminUrl + "/act.htm";
document.diamondSingleStoneLabForm.suid.value =value1;
document.diamondSingleStoneLabForm.obj.value = tempObj;
document.diamondSingleStoneLabForm.submit();
}
now, my question is
How to pass Object to specified action..???
Or How to pass obj.name property value (I cant access it using document.diamondSingleStoneLabForm.obj.name.value = nameVal;)..???
Hope in your jsp page you have a text field like this :
<input type="text" name="obj" value="<%= rs.getString(n)%>" >
but you should tally with the modelform & jsp(this will be your logical part) page where from you fetch the value like <%= rs.getString(n)%>
then you can do this thing
var obj = obj_value;
var action = adminUrl + "/act.htm";
document.diamondSingleStoneLabForm.action = action ;
document.diamondSingleStoneLabForm.submit();
Or you can use: jQuery.post() method in this format
jQuery.post( url [, data] [, success(data, textStatus, jqXHR)] [, dataType] )
you can take a look of this link: jQuery.post()

Categories

Resources