AJAX post JSON data from Javascript to Grails - javascript

I'm trying to POST JSON formatted data from Javascript (using Prototype) to Grails. My Javascript code is:
var JSONObject = new Object;
JSONObject.id = "23";
JSONObject.name = "Test 1";
JSONstring = JSON.stringify(JSONObject);
var url = "${createLink(controller:'testController', action:'receiveJson')}";
new Ajax.Request(url, {
method:'post',
contentType:'application/json',
parameters:JSONstring,
asynchronous:true,
onSuccess: function (req) {
sendInfoResponse(req.responseText);
}
});
and the code in my Grails controller is:
def receiveJson = {
def json = request.JSON;
}
However, the 'json' variable appears to be empty in my tests. I'd be so grateful if someone could explain what I'm doing wrong. Many thanks.

In your Ajax.Request options change
parameters:JSONstring,
to
postBody:JSONstring,
The problem with using parameters is that it URL encodes the data so that the request body ends up looking like this:
%7B%22id%22%3A%2223%22%2C%22name%22%3A%22Test%201%22%7D&_=
Instead of the desired (which is what you get with postBody):
{"id":"23","name":"Test 1"}

Good question mfloryan - I was doing the testing manually, i.e. not as part of a unit or integration test.
Thanks very much for the help hvgotcodes. I made the changes to my code as you have suggested, but unfortunately to no avail. Interestingly, if I print request.JSON I get {}, whereas if I print request.json I get null.
EDIT: By 'printing' I mean using: request.JSON.toString()
EDIT: Thank you all so much for the help. Once I'd made the final change John Wagenleitne suggested the code began working properly. I'm very grateful indeed for all your help.

I don't think you are invoking the Ajax.Request correctly. From the documentation, the parameters option:
"The parameters for the request, which will be encoded into the URL for a 'get' method, or into the request body for the other methods. This can be provided either as a URL-encoded string or as any Hash-compatible object (basically anything), with properties representing parameters."
I think you need to do something like
...
parameters: {json: JSONString}
...
and then in your controller
request.json
note the form of the parameters object literal - it tells the Prototype library to make the request key 'json' and the request value be the json string. You access the key off the request object in the controller.
EDIT -- I just realized you're javascript block is jacked up.
This:
var JSONObject = new Object;
should be something like
var JSONObject = new Object();
...
you might also be able to do just an object literal, so
var jsonObject = {};
....

Related

Using javascript/html to grab one piece of data from JSON result

Before I start, I'm complete beginner and I hope I'm not misusing terms when I ask my question.
I'm starting off writing an HTML5/Javascript application using Intel XDK to query barcodes of videos games from an online api, and I only need one piece of the JSON result (the title of the game) to then go on and use within my app.
The JSON result looks like this:
{"0":{"productname":"The Elder Scrolls V: Skyrim","imageurl":"http://ecx.images-amazon.com/images/I/413Gdr3FzqL._SL160_.jpg","producturl":"","price":"14.00","currency":"USD","saleprice":"","storename":"N/A"},"1":{"productname":"Skyrim X360","imageurl":"http://ecx.images-amazon.com/images/I/41QbF1Vg5KL._SL160_.jpg","producturl":"","price":"18.00","currency":"USD","saleprice":"","storename":"N/A"},"2":{"productname":"Bethesda Softworks Skyrim X360","imageurl":"http://ecx.images-amazon.com/images/I/41X97hqaJwL._SL160_.jpg","producturl":"","price":"23.95","currency":"USD","saleprice":"","storename":"N/A"},"3":{"productname":"BETHESDA SOFTWORKS 11763 / Skyrim X360","imageurl":"http://ecx.images-amazon.com/images/I/41IaEzP-6pL._SL160_.jpg","producturl":"","price":"34.00","currency":"USD","saleprice":"","storename":"N/A"}}
All I want to use in my app is that very first 'productname' entry.
The JSON is from an api provider I have an account with so it's on a remote URL for examples sake we'll call the URL: http://JsonIs.here
I want to be able to query the JSON URL and return "The Elder Scrolls V: Skyrim" as a string which I can then go on to use elsewhere in the application.
I've got my barcode scanning working, I can create the GET request URL already, I just don't know where to start calling that URL and then returning the small piece of information I need.
You can use jQuery's $.getJSON for this. The method returns a promise which has a nice easy-to-understand API.
var productName;
$.getJSON('http://JsonIs.here').then(function (data) {
productName = data[0].productname;
});
A couple of things to note here. 1) getJSON is an asynchronous process, so productName won't be immediately available, so you might have to restructure your code a little to account for this. You can't, for example do this:
var productName;
$.getJSON('http://JsonIs.here').then(function (data) {
productName = data[0].productname;
});
console.log(productName); // undefined
You may find this article useful as it covers how to return a value from an async process in depth.
2) getJSON automatically parses the JSON so you don't have to which is why, in the example, I've called the argument data and not json to save confusion.
To simulate you getting your JSON
var getJSON = function(){
return '{"0":{"productname":"The Elder Scrolls V: Skyrim","imageurl":"http://ecx.images-amazon.com/images/I/413Gdr3FzqL._SL160_.jpg","producturl":"","price":"14.00","currency":"USD","saleprice":"","storename":"N/A"},"1":{"productname":"Skyrim X360","imageurl":"http://ecx.images-amazon.com/images/I/41QbF1Vg5KL._SL160_.jpg","producturl":"","price":"18.00","currency":"USD","saleprice":"","storename":"N/A"},"2":{"productname":"Bethesda Softworks Skyrim X360","imageurl":"http://ecx.images-amazon.com/images/I/41X97hqaJwL._SL160_.jpg","producturl":"","price":"23.95","currency":"USD","saleprice":"","storename":"N/A"},"3":{"productname":"BETHESDA SOFTWORKS 11763 / Skyrim X360","imageurl":"http://ecx.images-amazon.com/images/I/41IaEzP-6pL._SL160_.jpg","producturl":"","price":"34.00","currency":"USD","saleprice":"","storename":"N/A"}}';
};
a function that gets the JSON and creates an array that holds all your productnames
var getProductName = function(){
// get the JSON_string ;)
var JSON_string = getJSON();
// convert it to an obj.
var JSON_obj = JSON.parse(JSON_string);
//create something to store your data in, you don't need to do this ofcourse
var r_productNames = [];
for(var key in JSON_obj){
if(JSON_obj.hasOwnProperty(key)){
r_productNames.push(JSON_obj[key].productname);
}
}
// et voila, you have an array of all the productnames, returned by your request.
console.log(r_productNames);
};
It works for me ;)
Json comes with a key value pair and the indexing starts with 0. Hence json[0] that means json in first index. json[0].productname here productname is the key which will give the value in return
var json = {"0":{"productname":"The Elder Scrolls V: Skyrim","imageurl":"http://ecx.images-amazon.com/images/I/413Gdr3FzqL._SL160_.jpg","producturl":"","price":"14.00","currency":"USD","saleprice":"","storename":"N/A"},"1":{"productname":"Skyrim X360","imageurl":"http://ecx.images-amazon.com/images/I/41QbF1Vg5KL._SL160_.jpg","producturl":"","price":"18.00","currency":"USD","saleprice":"","storename":"N/A"},"2":{"productname":"Bethesda Softworks Skyrim X360","imageurl":"http://ecx.images-amazon.com/images/I/41X97hqaJwL._SL160_.jpg","producturl":"","price":"23.95","currency":"USD","saleprice":"","storename":"N/A"},"3":{"productname":"BETHESDA SOFTWORKS 11763 / Skyrim X360","imageurl":"http://ecx.images-amazon.com/images/I/41IaEzP-6pL._SL160_.jpg","producturl":"","price":"34.00","currency":"USD","saleprice":"","storename":"N/A"}}
alert(json[0].productname);
Try using ajax
$.ajax({
type: 'GET',
url: 'http://JsonIs.here',
dataType: "json",
success: function(data) {
console.log(data[0].productname)
},
error: function(data) {
}
});
Using ajax you can try to get the data from the url and you can get the data in the success of the request
Here you go. However I find "0" as key in your JSON response somewhat not seen till today. It is better practice to start of with a character.
Your JSON response have one object. You can access the element in the object by index. Here on 0th index you have your data. The reason we are accessing it as a[0].key where key represent name of key you want to access from the object.
This is how you can get the data from JSON and use it in your application to achieve rest of your functionality as per your question.
var a = {"0":{"productname":"The Elder Scrolls V: Skyrim","imageurl":"http://ecx.images-amazon.com/images/I/413Gdr3FzqL._SL160_.jpg","producturl":"","price":"14.00","currency":"USD","saleprice":"","storename":"N/A"},"1":{"productname":"Skyrim X360","imageurl":"http://ecx.images-amazon.com/images/I/41QbF1Vg5KL._SL160_.jpg","producturl":"","price":"18.00","currency":"USD","saleprice":"","storename":"N/A"},"2":{"productname":"Bethesda Softworks Skyrim X360","imageurl":"http://ecx.images-amazon.com/images/I/41X97hqaJwL._SL160_.jpg","producturl":"","price":"23.95","currency":"USD","saleprice":"","storename":"N/A"},"3":{"productname":"BETHESDA SOFTWORKS 11763 / Skyrim X360","imageurl":"http://ecx.images-amazon.com/images/I/41IaEzP-6pL._SL160_.jpg","producturl":"","price":"34.00","currency":"USD","saleprice":"","storename":"N/A"}}
a[0].productname;

xPages - set javascript variable by reading JSON from URL

I have an xAgent (based on JSONandRest example in openntf by Nikolas Heildoff) which returns me a json. this xpage is nothing by there is a call to java method which returns JSON.
My problem is to have this JSON read into a JS variable so I am able to play with it.
I would like to do something like:
var myJson = getJson("Json.xsp")
Thanks in advance
Arun
You can use the fromJson method:
var json = "{a:'123', b: 'abc'}";
var obj = fromJson( json );
println( obj.a );
This sends 123 to the console.

Returning single ID in JSON from a web service

I'm fairly new to working with client-side coding and was wondering what the the best way of returning a single ID from a simple Insert in a web service would be.
Copying code that returns more complex JSON objects, I'm doing the following:
Dim JaggedArray As String()() = New String(0)() {}
Dim i As Integer = 0
JaggedArray(i) = New String() {<insert stmt, returns integer>}
Dim js As New JavaScriptSerializer()
Dim strJSON As String = js.Serialize(JaggedArray)
Return strJSON
I then use the following to access the ID in Javascript (excerpt from the AJAX call):
success: function(data) {
var c = eval(data.d);
var testID = c[0][0];
Surely there's a less clunky way of doing this, right?
And this is a stupid question, but can (and / or should) you put code outside of the Success callback, or is this mandatory?
Surely you can use jqXHR.done An alternative construct to the success callback option, the .done(),
for more info visit http://api.jquery.com/jQuery.ajax/
$.ajax({
//ajax stuff ..
})
.done(function(return){
var output = "hello";
return output;
});

How to default construct JavaScript object from JSON Schema?

I've started using Newtonsoft.Json.Schema.JsonSchemaGenerator along with various property attributes over in my C# code to help keep my client script DRY. What I'd like to do is create a default initialized object client-side based on the schema from the server. This would be useful for, say, when the user clicks 'New Foo' to add a new entry into a table.
Obviously I can just code it up to iterate the .Properties and build up the new object, which is what I'm doing at the moment. However I'd prefer to avoid reinventing any wheels.
Are there any JS libraries for working with JSON schema that will do this, among other nifty things I've yet to realize I need?
1/29/2013 UPDATE
Some people have attempted to answer my question and have been off base, and as a result have received some negative feedback from the SO community. So let me attempt to clarify things. Here is the challenge:
In JS client script, you have an object that represents the JSON Schema of another object. Let's say, this came from the server via JSON.NET and is the representation of a C# class.
Now, in the JS client script, create one of these objects based upon the JSON Schema. Each field/property in the object must be default initialized according to the schema, including all contained objects!
BONUS: Bind this new object to the UI using MVVM (eg Knockout). Change some of the fields in response to user input.
Send this new object to the server. The server-side code will add it to a collection, database table, whatever. (Yes, the object will be sent as JSON using Ajax -- we can assume that)
No duplication! The only place where the class is defined is in the server-side code (C# in my example). This includes all metadata such as default values, description text, valid ranges, etc.
Yes there is (I tried it with NodeJS):
JSON Schema defaults
Link updated.
i think...you have to use two way binding with your HTML code...so, once your client side change you will get on your costume js file.
check here for knockout js.
Knock Out JS Link
and on C# code use : $("#urlhidden").val() OR Document.GetElemenyByID("#urlhidden").val().
here you will get array/list or textbox value
Use json with Ko
create new viewmodel for knockout js which you will get the idea about on above link.
and create a json call
like:
self.LoadMAS_Client = function () {
try {
var params = { "clientID": ClientId };
$.ajax({
type: "POST",
url: "http://" + ServerString + "/Services/LogisticsAppSuite-Services-Web-Services-MasClientService.svc/Json/GetAllLevelSubClients",
contentType: 'application/json',
data: JSON.stringify(params),
dataType: 'json',
async: false,
cache: false,
success: function (response) {
// in response u will get the data.and use as per your requirement.
eg. self.SelectedClient(response.your value);
},
error: function (ErrorResponse) {
}
});
}
catch (error) {
}
};
================================New Update ==========================================
i think..one way you can do...get data on xml format at C# code and covert into json string...check below code // To convert an XML node contained in string xml into a JSON string
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string jsonText = JsonConvert.SerializeXmlNode(doc);
// To convert JSON text contained in string json into an XML node
XmlDocument doc = (XmlDocument)JsonConvert.DeserializeXmlNode(json);

JSON/AJAX and Facebook

I'm currently creating a facebook fan page (www.facebook.com.SSBMstream), and I am using a static html app to create a section that will allow users to select a twitch.tv stream they wish to watch using a button. I want to go one step further and list channels based on whether or not they are 'live' or offline. Twitchtv/Justintv already has an api set up for exactly that (http://api.justin.tv/api/stream/list.json?channel=) where you can just plug in the channel name and get '[]' if it is not live and what I believe is JSON if it is. How to dynamically check each channel in my array to determine if it is live and, if possible, access the information in that api to allow me to update titles and the like?
EDIT: Here's the hollowed out version of my code (Only the part I'm having trouble with)
I'm having it return the information from the other page as a debugger so I can test whether or not (if/when) it's working.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function loadJSON()
{
var xmlhttp;
if (window.XMLHttpRequest)
{
xmlhttp=new XMLHttpRequest();
}
else
{
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4)
{
document.getElementById("div1").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","http://api.justin.tv/api/stream/list.json?channel=ignproleague",true);
xmlhttp.send();
}
</script>
</head>
<body>
<div id="div1"><h2>Just a test</h2></div>
<button type="button" onclick="loadJSON()">Change Content</button>
</body>
</html>
It depends on how twitch defines what is live and what isn't. Sorry I'm not super familiar with twitch's API but if it returns an empty array if the channel isn't live you could simply check if (array.length == 0).
If you are given a JSON object, then just interact with the appropriate information you need. I don't know exactly how twitch formats their JSON objects but here is an example. Let's say it returned this JSON object:
var JSONobj = {
"channelName": "e-sports", "channelTheme: "Professional Gaming", "viewerCount": 100
};
To retrieve the information you would just have to call the appropriate field.
var chan = JSONobj.channelName; //chan = "e-sports
var theme = JSONobj.channelTheme; //theme = "Professional Gaming"
Hope this helps
EDIT: It seems you need help with understanding AJAX. Let me just give you a rough idea of what the syntax is. I personally use a framework called Prototype.js
new Ajax.Request(WEB_SERVICE, {
method: "get",
parameters: {"type" : type, "name" : name},
onSuccess: successCall,
onFailure: ajaxError,
onException: ajaxError
});
This is your pretty typical AJAX request. When this is called, it'll throw an AJAX request to a WEB_SERVICE (generally a PHP document that will get the parameters passed and then calculate something from it). In this scenario the method being passed is "GET" and the parameters being passed is in the form of an object with the fields "type" and "name". successCall is a method that is called when the AJAX request successfully is passed and returns the ajax that has been calculated. I'm assuming in your scenario your AJAX should be receiving some information in a JSON format so its important your successCall function not only gets back that information, but parses through it as if it were JSON. Your successCall function would look something like this:
function successCall(ajax) {
var info = JSON.parse(ajax.responseText);
Hopefully from here you have a good understanding of what's going on. Try to work with this and if you still need help, just comment.
Oh and I didn't see that other comment. If you want to MAKE a JSON object you can do so like this.
var JSONobj = {};
JSONobj.field = something;
Your JSON object would then look something like this:
JSONobj = { "field" : something };
It is important you stringify the JSONobj if you want to pass it as a String. I guess it depends on how your WEB_SERVICE is handling it and you can do so like this.
var stringJSON = JSON.stringify(JSONobj);
Hope this helps.

Categories