I am trying to make a call with this script, but am getting a "Uncaught SyntaxError: Unexpected token :"
I can't figure out where I'm going wrong, I don't know if it's something with my callback. I am sending a valid JSON packet so I don't think that's the issue. Anyway, here's my html/jquery call:
<script>
function loadJSON(){
$.getJSON("http://localhost:8000/api/0.1/tonight-mobile.json&callback=?", function(data){
alert('hey');
$('result').append(data);
alert('hey 2');
$.each(data, function(i, json){});
});
alert('hey 3');
}
</script>
With this corresponding function in my django view:
def tonight_mobile(request):
callback = request.GET.get('callback', '')
def with_rank(rank, place):
return (rank > 0)
place_data = dict(
Places = [make_mobile_place_dict(request, p) for p in Place.objects.all()]
)
xml_bytes = json.dumps(place_data)
return HttpResponse(xml_bytes, content_type='application/json; charset=utf-8')
Here is my request being logged by my server (so I know its at least getting that far with a OK status code):
"GET /api/0.1/tonight-mobile.json&callback=jsonp1293142434434 HTTP/1.1" 200 167
Displaying this error in my javascript console:
Uncaught SyntaxError: Unexpected token : tonight-mobile.json&callback=jsonp1293142434434:1
If you need to see my JSON format (if that is what's causing this) please let me know and I can post it too.
Thank you in advance for your help!
UPDATE:
Here's the response coming from my server:
{"Places": [{"url": "http://localhost:8000/api/0.1/places/1.plist", "image_url": "http://localhost:8000/static/place_logos/Tsonoqua_Mask.gif", "name": "Boo's Place"}]}
[23/Dec/2010 17:37:22] "GET /api/0.1/tonight-mobile.json&callback=jsonp1293147441552 HTTP/1.1" 200 167
UPDATE 2:
I've managed to get my callback working correctly! Here's the code:
Client side:
<script>
function loadJSON(){
$.getJSON("http://localhost:8000/api/0.1/tonight-mobile.json&callback=?", logIt(data));
}
function logIt(data){
window.console && console.log(data);
alert('yay!');
}
</script>
Server side:
def tonight_mobile(request):
callback = request.GET.get('callback', 'logIt')
def with_rank(rank, place):
return (rank > 0)
place_data = dict(
Places = [make_mobile_place_dict(request, p) for p in Place.objects.all()]
)
xml_bytes = json.dumps(place_data)
if callback:
xml_bytes = '%s(%s)' % (callback, xml_bytes)
print xml_bytes
return HttpResponse(xml_bytes, content_type='application/javascript; charset=utf-8')
This returns the following response:
logIt({"Places": [{"url": "http://localhost:8000/api/0.1/places/1.plist", "image_url": "http://localhost:8000/static/place_logos/Tsonoqua_Mask.gif", "name": "Boo's Place"}]})
Is this how it should function? It seems I should be able to simplify the getJSON call... I just want to make sure I've done everything I need to correctly with my callback before I continue forward parsing the response and setting them to elements on the page.
UPDATE 3*
So, I've made quite some progress!! I'm using Jquery mobile, so ignore some of the following overdone css, its not related to the core issue.
I'm having a problem looping over the "Places" in my JSON packet. I am getting a response with multiple "Places", but can't seem to figure out how to iterate over them. My 'i' variable in my each loop is working correctly for the first element, and displaying its corresponding name & image.
My getJSON and callback method have evolved into this:
<script>
function loadJSON(){
$.getJSON("http://localhost:8000/api/0.1/tonight-mobile.json&callback=?", callback(data));
}
function callback(data){
$("#tonight-list").each(data.Places, function(i) {
$(this).append("<li role='option' tabindex='" + data.Places[i] + "' class='ui-li-has-thumb ui-li ui-btn ui-btn-icon-right ui-corner-top ui-corner-bottom ui-controlgroup-last ui-btn-down-c ui-btn-up-c' data-theme='c'><div class='ui-btn-inner ui-corner-top ui-corner-bottom ui-controlgroup-last'><span class='ui-icon ui-icon-arrow-r'></span><div class='ui-btn-text'><img src=" + data.Places[i].image_url + " alt=" + data.Places[i].name + " class='ui-li-thumb ui-corner-tl ui-corner-bl'/><h1 class='list-title ui-li-heading' id='list-title'><a href='detail.html?id=slide' data-transition='slide' class='ui-link-inherit'>" + data.Places[i].name + "</a></h1><span class='ui-li-count ui-btn-up-c ui-btn-corner-all'>" + data.Places[i].events + " events</span></div></div></li>");
});
}
</script>
Here's my response:
callback({"Places": [{"url": "http://localhost:8000/api/0.1/places/3.plist", "image_url": "http://localhost:8000/static/place_logos/Bengals_1.png", "name": "Big 12", "events": 2}, {"url": "http://localhost:8000/api/0.1/places/2.plist", "image_url": "http://localhost:8000/static/place_logos/Makonde_Mask.gif", "name": "Harpo's", "events": 0}, {"url": "http://localhost:8000/api/0.1/places/1.plist", "image_url": "http://localhost:8000/static/place_logos/Quintons_1.png", "name": "Quinton's", "events": 1}]})
Am I confusing how the each function iterates over the JSON (which become) Javascript objects? I am pretty sure the each is my issue here, as I am only getting the FIRST element of the "Places" list. Can someone please help me out?
Yes to return jsonp you need to wrap the response in a function:
def tonight_mobile(request):
callback = request.GET.get('callback')
def with_rank(rank, place):
return (rank > 0)
place_data = dict(
Places = [make_mobile_place_dict(request, p) for p in Place.objects.all()]
)
xml_bytes = json.dumps(place_data)
if callback:
xml_bytes = '%s(%s)' % (callback, xml_bytes)
return HttpResponse(xml_bytes, content_type='application/json; charset=utf-8')
That looks good, you could simplify the getJSON call like this:
function loadJSON(){
var url = "http://localhost:8000/api/0.1/tonight-mobile.json&callback=?";
$.getJSON(url, function(data){
if(data){
console.log(data.name);
}
});
}
In your python code I would do
callback = request.GET.get('callback')
instead of
callback = request.GET.get('callback', 'logIt')
so if callback is not provided json will be returned instead of jsonp.
You're mixing JSON and JSONP. Your Django script is returning a JSON object, when jQuery is expecting a JSON object wrapped with the callback argument:
callback(JSON string);
Related
Basically, I am trying to debug a code that was written long back by someone.
I have a jsp which is calling a javascript function on click of a button. In the javascript there is an ajax call happening to the Struts Action class. The Action class returns an Array List of objects to the jsp. My Array List has an inner list of objects too. Everything works fine when the list is small. But when the returned list is big, the ajax variable "data" returns as empty after a long time.
i think it is something to do with handling large data in the response. When i googled a few forums, i think the size of the response is exceeding a maximum limit and then returned as empty. When the response is small the variable "data" returns with a html reponse. But when it is huge, the variable has nothing.
Below is the ajax call. Since this is happening in production right now, any quick help is really appreciated. BTW, i am using Websphere 8.5.5.
function submitCriteria(submitSrc) {
var nameOfFormToPost = "criteriaForm";
var spanId = "resultDataSpan";
var formAsString = getFormAsString(nameOfFormToPost, submitSrc);
$.ajax({
type: "POST",
dataType: 'html',
url: "matchReconcileHome.do?execute=viewMatchResult",
data: formAsString,
success: function(data, textStatus) {
idx = data.indexOf("<title>XXXXXXX- XXXXX - Login</title>");
if (idx > 0 && idx < 500) {
window.location = "/pdrWeb/Login.jsp";
}
//Split the text response into Span elements
spanElements = splitTextIntoSpan(data, spanId);
//Use these span elements to update the page
replaceExistingWithNewHtml(spanElements);
$("#matchResult").treeTable();
setPageNavigation();
setResultControls();
//alert("Ajax called back Done" );
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("Problem with server response:\n " + textStatus + ", Error: " + errorThrown);
}
});
return false;
}
I will start by saying that I am learning how to program in jquery/javascript, and am running into an issue using JSON.parse(). I understand the format, and why people use it... but have not been able to get it to work in any of my code projects.
I have read in books/online on here in how to use it, but I think I read too much on it. I am now confused and second guessing what I know about it.
With that said, my jquery/javascript class I am taking is asking me to use it for an assignment, through AJAX using MAMP/localhost as the server.
The two codes below are for the section that I need to fill in the //TODO information. One is javascript (client-side), the other is php (server-side). I think that I've set the other //TODO information correctly, but I keep getting a token error for the JSON part.
I looked on here for a solution, but again, I think I've confused myself badly and need help. Appreciate any feedback, insight, or information.
-Javascript-
var calculateMpg = function () {
// These lines are commented out since the server will perform these checks
// if (!checkNumber("miles") || !checkNumber("gallons")) {
// return;
// }
var miles = $("#miles").val();
var gallons = $("#gallons").val();
console.log("ajax request issued.");
var result;
$.ajax({
url: "service.php?action=calculateMPG&miles="+miles+"&gallons="+gallons,
cache: false,
dataType: "text",
success: function(msg) {
console.log("ajax response received.");
// TODO: parse the JSON string returned from the server (see JSON.parse())
JSON.parse("result");
if (result.status === 'success') {
// TODO: get the mpg value returned from the server and display it to the user.
$("#mpg").val($_GET("result"));
console.log("JSON Working!");
}
else {
// TODO: get the name of the variable with the error. Hint: look at the 'fail' result from service.php
$_GET[fail(id)];
// TODO: report the error to the user using invalidNumber() function.
alert("{status: 'failure', variable: <variable name>}");
}
}
});
};
$(document).ready( function () {
$("#miles").blur(function () {
checkNumber("miles");
});
$("#gallons").blur(function() {
checkNumber("gallons");
});
$("#calculate").click(calculateMpg);
$("#miles").focus();
});
-PHP-
<?php
if ($_GET) {
if ($_GET['action'] == 'calculateMPG') {
$miles = htmlspecialchars($_GET['miles']);
$gallons = htmlspecialchars($_GET['gallons']);
// validate miles
if (strlen($miles) == 0) {
fail("miles");
}
$miles_chars = str_split($miles);
for ($i=0; $i< count($miles_chars); $i++) {
if ($miles_chars[$i] < "0" || $miles_chars[$i] > "9") {
//error_log("miles_chars check failed at: " + $i);
fail("miles");
}
}
// validate gallons
if (strlen($gallons) == 0) {
fail("gallons");
}
$gallons_chars = str_split($gallons);
for ($i=0; $i< count($gallons_chars); $i++) {
if ($gallons_chars[$i] < "0" || $gallons_chars[$i] > "9") {
fail("gallons");
}
}
// validate $miles and $gallons calling $fail along the way
$result = $miles/$gallons;
if ($result) {
success($result);
} else {
fail("mpg");
}
exit ;
}
}
function fail($variable) {
die(json_encode(array('status' => 'fail', 'variable' => $variable)));
}
function success($message) {
die(json_encode(array('status' => 'success', 'message' => $message)));
}
Edited Additional 1
I have made changes to the JSON information in regard to 'var result' (thanks to several of the responses here). I'm starting to understand JSON a bit better.
Another question I have (now) is how to isolate a part of the JSON message from the whole being transmitted?
A piece of the 'JSON.parse(msg)' returned DOES include the answer to the equation miles/gallons, but I don't know how to... extract it from the JSON.
The solution to the equation miles/gallons appears in the 'msg' output.
Thanks.
Edited Additional 2
This question has been solved! While perusing around stackoverflow for a solution to the question in my previous edited section, I found my answer here: JSON response parsing in Javascript to get key/value pair.
The answer is this: under the //TODO section asking for the mpg value, I put the following code - $("#mpg").val(result.message); - which says that in the JSON section of the variable result, take the part of the JSON marked 'message', the value being the equation solution.
Thank you to all who responded with their solutions to my problem. I appreciate the fast responses, the great suggestions, and the information in understanding JSON.
-ECP03
JSON.parse() requires that you send it a valid JSON string.
"result" is not a valid JSON string. In your success function you have defined a parameter msg - what does this contain? Try console.log(msg) at the beginning of your success function and look at the console output.
You have two options:
Option 1: -- Parse the string returned.
Change JSON.parse("result"); to:
var result = JSON.parse( msg );
Option 2: -- Request JSON instead of plain text - no need to parse
Use $.getJSON() which is shorthand for:
$.ajax({
dataType: "json",
url: url,
data: data,
success: success
});
Instead of parsing the JSON yourself, jQuery already provides you with a convenient function that will parse JSON:
var path = "service.php?action=calculateMPG&miles="+miles+"&gallons="+gallons;
$.getJSON(path, function (data) {
if (data.status == 'success') {
console.log('Success! Message:', data.message);
} else {
console.log('Failed :( Variable:', data.variable);
}
});
For your original code, what you would need to do is call JSON.parse(msg) in your success callback, which would return a JavaScript object with the values you sent from your PHP script. By specifying dataType: 'json' in the $.ajax call, jQuery does this for you. The $.getJSON method does this and some other things for you.
You need to use the result returned by the success function:
var result = JSON.parse(msg);
Then, you could do stuff like result.status.
When you put JSON.parse("result") you're saying "parse the string 'result'," which doesn't make any sense. However, if you say JSON.parse(msg) you're saying "Parse the variable that was returned from the ajax action," which makes sense.
JSON.parse() is used to convert your json data to object, then you can manipulate it easly.JSON.parse(msg); instead of JSON.parse("result").
For example:
var json = '{"value1": "img", "value2":"img2"}'
var obj = JSON.parse(json);
for ( k in obj ) {
console.log(obj[k])
}
This is totally wrong: JSON.parse("result");. .parse() expects a JSON string, e.g. the string that came back from you ajax request. You're not providing that string. you're providing the word result, which is NOT valid JSON.
JSON is essentially the right-hand side of an assignment expression.e.g.
var foo = 'bar';
^^^^^---this is json
var baz = 42;
^^---also json
var qux = ['a', 'b', 'c'];
^^^^^^^^^^^^^^^---even more json
var x = 1+2;
^^^---**NOT** json... it's an expression.
What you're doing is basically:
var x = parse;
^^^^^^---unknown/undefined variable: not JSON, it's an expression
I know this is a long shot, but I'm trying to make a POST with AJAX within the Javascript tool in HPSM. It's got very limited debugging capabilities so I'm stuck where it should be simple (or so I thought). From the syntax I've seen in other articles, calling that AJAX function should be right, but it doesn't seem to want to take it.
Thanks for any help
Here is the code I'm calling, and using jQuery library v1.11.2
var JSONdata = {
"eId": "xxx111",
"deviceToken": "111111111111",
"deviceType": "iphone",
"applicationName": "huds"
};
system.library.jQuery.ajax({
type: "POST",
url: 'http://place:11400/location/collaboration/notifications/register/',
data: JSONdata,
dataType: "json",
cache: false,
crossDomain: true,
processData: true,
success: function (data) {
alert(JSON.stringify(data));
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("error");
}
});
errors
Process panel calc.javascript in RAD format.cjavascript encountered error in line 5 (format.cjavascript,calc.javascript)
Cannot evaluate expression (format.cjavascript,calc.javascript)
Cannot evaluate expression (format.cjavascript,calc.javascript)
Cannot evaluate expression (format.cjavascript,calc.javascript)
Cannot evaluate expression (format.cjavascript,calc.javascript)
Script <UNKNOWN> line 20: ERROR TypeError: system.library.jQuery.ajax is not a function at char 1
Script 'jQuery' line 925: ERROR TypeError: document has no properties at char 1
Unrecoverable error in application: se.call.process on panel call.rad.1
Unrecoverable error in application: cm.update.save on panel call.master.upd
Unrecoverable error in application: format.cjavascript on panel calc.javascript
I'm assuming you have a ScriptLibrary called jQuery in your HPSM, right?
Try with
lib.jQuery.ajax(...
instead of system.library, regards.
not sure if you have imported the jQuery as a ScriptLibrary, but I think it will not work, because the code inside the jQuery Library includes some lines of code which are not valid for the HPSM.
Anyway...
To call an external external RESTful Service, you can use the doHTTPRequest() function in your ScriptLibrary.
What it is, what parameters are needed etc. can be found in the Programming Guide:
http://86.48.81.222:6080/classic/Content/Resources/PDF/sm_programming_guide.pdf
See Page 266 ...
Here an short example how it should work (it calls the REST API from the HPSM to create a new incident:
var objConfig = {
"url" : "http://place:11400",
"path" : "/location/collaboration/notifications/register/",
"connect_timeout" : 30,
"read_timeout" : 30
};
var objPostData = {
"eId": "xxx111",
"deviceToken": "111111111111",
"deviceType": "iphone",
"applicationName": "huds"
};
createRecord( objPostData );
/**
* Create a new Incident with the RESTful API
*
* #param {Object} objRecord Object with all required fields
*
*/
function createRecord( objRecord ) {
var JSON = system.library.JSON.json();
var arrHeaders = [];
//Content Type application/json is required
//otherwise we will get an 501 error
var typeHeader = new Header();
typeHeader.name = "content-type";
typeHeader.value = "application/json";
var arrHeaders = new Array();
arrHeaders.push(typeHeader);
//build url for the request
//Default Action for POST is "create" so we don't need
//to add the action again
var cRequestUrl = objConfig.url+objConfig.path;
//convert the given object to an json string
cPostBody = system.library.JSON2.toJSON(objRecord);
try {
//lets run the the HTTP request
//HTTP Command - url to execute - http header - POST Body
var rcRequest = doHTTPRequest( "POST", cRequestUrl, arrHeaders, cPostBody, objConfig.connect_timeout, objConfig.read_timeout );
//convert response json string back to an object
var objResponse = JSON.parse(rcRequest);
print( objResponse.toSource() );
} catch( e ) {
//something goes wrong
//check also http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html
//to get the description of the given http response code like 401 etc.
//currently it's not possible (or i don't know how) to get the correct
//error response - for me it looks like that the HPSM has an filter
//which removes the response body if the response header is not 200
//if it's possible to use the reponse, we can use the same code
//as above JSON.parse() etc.
print("ERROR: \n"+e);
}
}
INFO1: Currently there is a limitation in the doHTTPRequest.
It can't handle the catch case correctly.
So even when there is an error, you will get the response as string.
And not the Object or whatever the response is.
INFO2: This example is based on my example to call the internal incident api.
I have modified it to your given data.
Code was created and tested successfully with HPSM 9.3+.
Hope this helps.
Greets
Marcus
Here is the script that attempts to get the json file:
jQuery(function($) {
//////////////////////HEADLINE NEWS JSON SERVER START///////////////////////////
var container = $("#headlineNews"); //cache the element
console.log("First Log message is here!")
$.getJSON("/JsonControl/Headline_News.json", function(jsonObj) {
console.log("Second Log message is here!")
var val = "";
for (var i = 0; i < jsonObj.news.length; ++i) {
val += "<div id='newsHeading'>"
+ jsonObj.news[i].heading
+ "</div><br/><div id='newsSummary'>"
+ jsonObj.news[i].summary
+ "</div><br/>";
if (jsonObj.news[i].linkText != "" && jsonObj.news[i].linkPath != "") {
val += "<a href='" + jsonObj.news[i].linkPath + "'>" + jsonObj.news[i].linkText + "</a><br/><br/>";
}
val += "<div class='entryDivider'>____________________________________________________</div>";
}
container.html(val);
});
//////////////////////HEADLINE NEWS JSON SERVER END/////////////////////////////
});
Here is the json file itself:
{
"news": [
{
"heading": "Bulky Item Pick-Up to Begin May 4th, 2012 for Residential Utility Account Holders.",
"summary": "Click on the link below for more details.",
"linkText": "Bulky Item Pick-Up",
"linkPath": "/Displayable Files/City_Bulk_Pick_Up_for_e_mailing.pdf"},
{
"heading": "NOW OPEN!",
"summary": "OKMULGEE RECYCLING CENTER<br/>301 E. 3rd Street<br/>(Corner of E. 3rd St. and N. Muskogee Ave.).",
"linkText": "WHAT TO AND WHAT NOT TO RECYCLE",
"linkPath": "/Displayable Files/Recycling_Items.pdf"}
]
}
//To omit any of these options, simply leave them blank (i.e., "linkText":"").
I have attempted to use console.log, but only the first one executes and the second one doesn't, so I know the contents of the $.getJSON branch isn't getting executed at all (meaning the $.getJSON statement is a fail, if I understand it correctly). However absolutely no script errors occur.
Also, the server IS set up to serve json files, as another tester site has executed an external json file just fine.
It feels like the path is wrong somehow, but I'm not getting a 404, and I've rechecked this path to make sure that it is syntactically correct at least a dozen times.
How can the $.getJSON command fail if the path to the file is correct, the syntax of the json file is correct, and the server definitely is configured to serve up json files (e.g., application/json MIME type is set)? Is there anything else it could possibly be or would the second console.log not execute if the rest of the branch doesn't?
-------------------UPDATE-----------------------------
I have edited my post to reflect comments that I (erroneously) had in my json file.
You should use $.ajax since it allows you to specify a success, error, and complete (finally) callback. Perhaps your callback isn't being called because it's a success callback and the request is returning an error.
$.ajax({
url: 'ajax/test.html',
type: 'POST',
data: jsonData
success: function(data) {
$('.result').html(data);
alert('Load was performed.');
},
error: function(request, status, error) {
//do stuff
}
});
Try this and see if you get json returned in the console.
$.getJSON("/JsonControl/Headline_News.json", function(jsonObj) {
console.log(jsonObj);
});
JavaScript comments (nor any other) aren't legal in JSON syntax.
Bit of a vague question, but I'm unsure how I can this to work. Firebug says the Json object (array?) from my ajax request looks like:
{
"jsonResult":
"[
{\"OrderInList\":1},
{\"OrderInList\":2}
]"
}
This is retrieved through through a $.getJSON ajax request:
$.getJSON("/Json/GetOrderSelectList?parentCategoryId=" + postData, testData, function (jsonResult) {
$('#orderInList option').remove();
var map = {
"TestKey1": "TestValue1",
"TestKey2": "TestValue2"
};
$.each(jsonResult, function (key, value) {
$("#orderInList").append($("<option value=" + key + ">" + value + "</option>")
);
});
If I replace $.each(jsonResult) with $.each(map) the select list populates correctly. Otherwise my select list just says 'undefined'.
I serialize the Json in this Action in my MVC Controller:
public JsonResult GetOrderSelectList(int parentCategoryId)
{
var result = Session
.QueryOver<Category>()
.Where(x => x.Parent.Id == parentCategoryId)
.OrderBy(x => x.OrderInList).Asc
.List();
var toSerialize =
result.Select(r => new {r.OrderInList});
var jsonResult = JsonConvert.SerializeObject(toSerialize);
return Json(new
{ jsonResult,
}, JsonRequestBehavior.AllowGet);
}
So I think the problem might be the format of Json the Action is responding with? Any help appreciated!
Edit for answer
Both of the answers below helped me. I couldn't seem to strongly type the variable jsonResult so thanks #JBabey for pointing out my error in reading the json property, and suggesting function (key, value) in the $.each statement.
Thanks #Darin Dimitrov for helping sort my controller out!
Your controller action is wrong. You are manually JSON serializing inside it and then returning this as a JSON result thus ending up with a double JSON serialization. You could directly return the array and leave the JSON serialization plumbing to the ASP.NET MVC framework:
public ActionResult GetOrderSelectList(int parentCategoryId)
{
var result = Session
.QueryOver<Category>()
.Where(x => x.Parent.Id == parentCategoryId)
.OrderBy(x => x.OrderInList)
.Asc
.List();
return Json(result, JsonRequestBehavior.AllowGet);
}
and then:
$.getJSON("/Json/GetOrderSelectList?parentCategoryId=" + postData, testData, function (jsonResult) {
$('#orderInList option').remove();
$.each(jsonResult, function () {
$('#orderInList').append(
$("<option value=" + this.Id + ">" + this.Value + "</option>")
);
});
});
Notice that I am using this.Id and this.Value here. This assumes that the JSON result looks like this:
[{"Id": 1, "Value": "some value"}, {"Id": 2, "Value": "some other value"}]
You will have to adapt those property names based on your actual Category model.
You are confusing a property of your data returned by your ajax with the data itself. $.each will work fine if you correct this.
Your data returned looks like this:
{
"jsonResult": "[
{\"OrderInList\":1},
{\"OrderInList\":2}
]"
}
Which means that is the object passed to your success function. Call it data instead of jsonResult.
function (data) {
...
$.each(data.jsonResult, function (key, value) {
...
});
});
Also, your array is coming through as a string, so you may need to parse it before $.each will be able to iterate it.