Hi I just tried testing if the error function would return an alert but it didn't fire. I altered the url link hoping that it would generate an alert since it won't be able to find or get json data. All I am getting is "Uncaught TypeError: Cannot read property 'length' of undefined jquery-1.9.1.min.js:3"
$(document).on('pagebeforeshow', '#blogposts', function () {
//$.mobile.showPageLoadingMsg();
$.ajax({
url: "http://howtodeployit.com/api/get_recent_po",
dataType: "json",
jsonpCallback: 'successCallback',
async: true,
beforeSend: function () {
$.mobile.showPageLoadingMsg(true);
},
complete: function () {
$.mobile.hidePageLoadingMsg();
},
success: function (data) {
$.each(data.posts, function (key, val) {
console.log(data.posts);
var result = $('<li/>').append([$("<h3>", {
html: val.title
}), $("<p>", {
html: val.excerpt
})]).wrapInner('');
$('#postlist').append(result).trigger('create');
return (key !== 4);
});
$("#postlist").listview();
},
error: function (data) {
alert("Data not found");
}
});
});
I think the problem is that, when you make the AJAX request your code is executing the success callback, not the error callback. Thus when you execute:
$.each(data.posts, function(key, val) {
The $.each function is trying to get the length of data which is NULL.
It doesn't look right that you have defined a jsonp callback function and yet your still using the success and error callbacks. This SO question might help a bit :
Use of success / jsonpCallback with ajax request
Maybe here $.each(data.posts, data.posts is undefined and that's why you get an error. Log data in success callback and see what it contains.
I created a clean Fiddle. Opening the given URL gives a 301 redirect followed by a 200 JSON response. The HTTP status code says that everything is fine, so jQuery doesn't know there was an error.
You mixed up two different concepts here: jQuery's error callback is for network errors and all these things. If you transport error states inside your JSON with HTTP status code 200 you have to deal with it on your own inside the success callback.
Sorry, SO doesn't allow JS-Fiddle links without code:
beforeSend: function() { console.log('beforeSend'); },
complete: function() { console.log('complete'); },
success:function (data) { console.log('success') },
error: function(data) { console.log('error') }
Thanks everyone for your input. I did take on-board all suggestions. Recommendation from Jason seems to had made more sense so while investigating his suggestion I came to this site to read up more about jasonCallback. removing the jasonCallback option though did not fix the issue but strangely this issue seems to do with the url I was using for my json caalback.
What I then did was to change the url from "http://howtodeployit.com/api/get_recent_po" to "http://howtodeployit.com/category/daily-devotion/feed/?json=recentstories" and it worked. Even though both returned error in the console but the second was the one that triggered the error function. Why I am looking into it.
Related
Is it possible to catch an error when using JSONP with jQuery? I've tried both the $.getJSON and $.ajax methods but neither will catch the 404 error I'm testing. Here is what I've tried (keep in mind that these all work successfully, but I want to handle the case when it fails):
jQuery.ajax({
type: "GET",
url: handlerURL,
dataType: "jsonp",
success: function(results){
alert("Success!");
},
error: function(XMLHttpRequest, textStatus, errorThrown){
alert("Error");
}
});
And also:
jQuery.getJSON(handlerURL + "&callback=?",
function(jsonResult){
alert("Success!");
});
I've also tried adding the $.ajaxError but that didn't work either:
jQuery(document).ajaxError(function(event, request, settings){
alert("Error");
});
Here's my extensive answer to a similar question.
Here's the code:
jQuery.getJSON(handlerURL + "&callback=?",
function(jsonResult){
alert("Success!");
})
.done(function() { alert('getJSON request succeeded!'); })
.fail(function(jqXHR, textStatus, errorThrown) { alert('getJSON request failed! ' + textStatus); })
.always(function() { alert('getJSON request ended!'); });
It seems that JSONP requests that don't return a successful result never trigger any event, success or failure, and for better or worse that's apparently by design.
After searching their bug tracker, there's a patch which may be a possible solution using a timeout callback. See bug report #3442. If you can't capture the error, you can at least timeout after waiting a reasonable amount of time for success.
Detecting JSONP problems
If you don't want to download a dependency, you can detect the error state yourself. It's easy.
You will only be able to detect JSONP errors by using some sort of timeout. If there's no valid response in a certain time, then assume an error. The error could be basically anything, though.
Here's a simple way to go about checking for errors. Just use a success flag:
var success = false;
$.getJSON(url, function(json) {
success = true;
// ... whatever else your callback needs to do ...
});
// Set a 5-second (or however long you want) timeout to check for errors
setTimeout(function() {
if (!success)
{
// Handle error accordingly
alert("Houston, we have a problem.");
}
}, 5000);
As thedawnrider mentioned in comments, you could also use clearTimeout instead:
var errorTimeout = setTimeout(function() {
if (!success)
{
// Handle error accordingly
alert("Houston, we have a problem.");
}
}, 5000);
$.getJSON(url, function(json) {
clearTimeout(errorTimeout);
// ... whatever else your callback needs to do ...
});
Why? Read on...
Here's how JSONP works in a nutshell:
JSONP doesn't use XMLHttpRequest like regular AJAX requests. Instead, it injects a <script> tag into the page, where the "src" attribute is the URL of the request. The content of the response is wrapped in a Javascript function which is then executed when downloaded.
For example.
JSONP request: https://api.site.com/endpoint?this=that&callback=myFunc
Javascript will inject this script tag into the DOM:
<script src="https://api.site.com/endpoint?this=that&callback=myFunc"></script>
What happens when a <script> tag is added to the DOM? Obviously, it gets executed.
So suppose the response to this query yielded a JSON result like:
{"answer":42}
To the browser, that's the same thing as a script's source, so it gets executed. But what happens when you execute this:
<script>{"answer":42}</script>
Well, nothing. It's just an object. It doesn't get stored, saved, and nothing happens.
This is why JSONP requests wrap their results in a function. The server, which must support JSONP serialization, sees the callback parameter you specified, and returns this instead:
myFunc({"answer":42})
Then this gets executed instead:
<script>myFunc({"answer":42})</script>
... which is much more useful. Somewhere in your code is, in this case, a global function called myFunc:
myFunc(data)
{
alert("The answer to life, the universe, and everything is: " + data.answer);
}
That's it. That's the "magic" of JSONP. Then to build in a timeout check is very simple, like shown above. Make the request and immediately after, start a timeout. After X seconds, if your flag still hasn't been set, then the request timed out.
I know this question is a little old but I didn't see an answer that gives a simple solution to the problem so I figured I would share my 'simple' solution.
$.getJSON("example.json", function() {
console.log( "success" );
}).fail(function() {
console.log( "error" );
});
We can simply use the .fail() callback to check to see if an error occurred.
Hope this helps :)
If you collaborate with the provider, you could send another query string parameter being the function to callback when there's an error.
?callback=?&error=?
This is called JSONPE but it's not at all a defacto standard.
The provider then passes information to the error function to help you diagnose.
Doesn't help with comm errors though - jQuery would have to be updated to also callback the error function on timeout, as in Adam Bellaire's answer.
Seems like this is working now:
jQuery(document).ajaxError(function(event, request, settings){
alert("Error");
});
I use this to catch an JSON error
try {
$.getJSON(ajaxURL,callback).ajaxError();
} catch(err) {
alert("wow");
alert("Error : "+ err);
}
Edit: Alternatively you can get the error message also. This will let you know what the error is exactly. Try following syntax in catch block
alert("Error : " + err);
Mayby this works?
.complete(function(response, status) {
if (response.status == "404")
alert("404 Error");
else{
//Do something
}
if(status == "error")
alert("Error");
else{
//Do something
}
});
I dont know whenever the status goes in "error" mode. But i tested it with 404 and it responded
you ca explicitly handle any error number by adding this attribute in the ajax request:
statusCode: {
404: function() {
alert("page not found");
}
}
so, your code should be like this:
jQuery.ajax({
type: "GET",
statusCode: {
404: function() {
alert("page not found");
}
},
url: handlerURL,
dataType: "jsonp",
success: function(results){
alert("Success!");
},
error: function(XMLHttpRequest, textStatus, errorThrown){
alert("Error");
}
});
hope this helps you :)
I also posted this answer in stackoverflow - Error handling in getJSON calls
I know it's been a while since someone answerd here and the poster probably already got his answer either from here or from somewhere else. I do however think that this post will help anyone looking for a way to keep track of errors and timeouts while doing getJSON requests. Therefore below my answer to the question
The getJSON structure is as follows (found on http://api.jqueri.com):
$(selector).getJSON(url,data,success(data,status,xhr))
most people implement that using
$.getJSON(url, datatosend, function(data){
//do something with the data
});
where they use the url var to provide a link to the JSON data, the datatosend as a place to add the "?callback=?" and other variables that have to be send to get the correct JSON data returned, and the success funcion as a function for processing the data.
You can however add the status and xhr variables in your success function. The status variable contains one of the following strings : "success", "notmodified", "error", "timeout", or "parsererror", and the xhr variable contains the returned XMLHttpRequest object
(found on w3schools)
$.getJSON(url, datatosend, function(data, status, xhr){
if (status == "success"){
//do something with the data
}else if (status == "timeout"){
alert("Something is wrong with the connection");
}else if (status == "error" || status == "parsererror" ){
alert("An error occured");
}else{
alert("datatosend did not change");
}
});
This way it is easy to keep track of timeouts and errors without having to implement a custom timeout tracker that is started once a request is done.
Hope this helps someone still looking for an answer to this question.
I have built my first website and it works on local server but not online. The problem is loading a json file with Ajax. In the published version I get the error message that my object is undefined.
This is a (simplified) version of my code that shows the problem:
$.ajax({
url: "json/torp.json",
contentType: "application/json",
success: function (data) {
torp = data;
console.log('great success!');
console.log(torp.items[3]);
},
error: function (/* request, error */) {
console.log('Network error has occurred please try again!');
}
This is the message in the console when running on local server:
great success! main.js:37:13
Object { id: "brunskar", title: "<h2>Brunskär</h2>", image: "img/countryside.jpg" }
But when I publish online this is what I get:
great success! main.js:37:13
TypeError: torp.items is undefined
In the Utilities Net section I get status code 200 and the whole content of the JSON file is readable under the "reply" tab, so it seems like the file is loaded. But I don't understand why my object is undefined.
Sounds like an asynchronous issue (your page is loading before your ajax call can return the data, therefor it is returned as undefined) one way to solve this is to put a function inside your ajax call that fires your page functions that use the data being returned by the call.
$.ajax({
url: "json/torp.json",
contentType: "application/json",
success: function (data) {
torp = data;
console.log('great success!');
console.log(torp.items[3]);
function usePageData (); <----calls webpage function utilizing
data
},
error: function (/* request, error */) {
console.log('Network error has occurred please try again!');
}
Hope that helps!
Problem solved by changing
contentType: "application/json"
to
dataType: "json"!
I used the tip from Patrick Evans in one of the comments. Thank you for the help!
My calls to $.post are not working all over my code. I'm not sending the request to other domains and, actually, I'm doing everything localhosted. My localhost alias was automatically defined by the Mac OS X 10.8 as ramon.local and I'm requesting from http://ramon.local/linkebuy_0.7/resourceX to http://ramon.local/linkebuy_0.7/resourceY. There are no errors on Chrome's console.
The server side doesn't receive the request and I can check it by accessing directly from the browser (typing the URL).
It's not just one call that is not working, none of them are. They were all working days ago and I'm suspicious that I accidentally changed something on my local settings. What could it be?
Here's an example of what I'm facing:
$.post(
<<CORRECT URL INSIDE THE DOMAIN>>,
{},
function(response) {
console.log('THIS SHOULD BE PRINTED ON CONSOLE');
alert('THIS SHOULD BE POPPED UP');
}
);
I don't get the alert, neither the console message while running the code above. So I tried the following:
$.support.cors = true;
$.ajax({
url: "http://ramon.local/linkebuy_0.7",
dataType: "json",
type: "GET",
crossDomain: true,
success: function (data) {
console.log(data);
},
error: function (xhr, status, error) {
alert(error + " - " + status);
}
});
I just came with $.support.cors = true; and crossDomain: true to check if it was a cross domain issue. So I was alerted No Transport - error same way as before.
What can I do to solve that?
Thanks in advance.
Try this and see if you are getting any alert:
// Assign handlers immediately after making the request,
// and remember the jqxhr object for this request
var jqxhr = $.post("your url", function() {
alert("success");
}).success(function() {
alert("second success");
}).error(function() {
alert("error");
}).complete(function() {
alert("complete");
});
// perform other work here ...
// Set another completion function for the request above
jqxhr.complete(function() {
alert("second complete");
});
Well, I solved the problem in a very strange way.
I deleted the JQuery file and downloaded it again, replacing the old one. Happens it worked out.
So, if you're:
Making AJAX requests that are not cross-domain;
Using JQuery for it (e.g. $.post, $.get, etc);
Getting No Transport AJAX error
Then re-download and replace you're JQuery source.
Else, if you're making cross-domain requests (not this case), then look for JSONP and try to set $.support.cors = true; at the beginning of you're code.
Thanks everyone for the comments and answers.
I've looked around for a while now, seen many similar problems, but none that help. I have a getJSON call that calls my Spring controller and responds with JSON text (Verified that JSON text is indeed being returned), but the callback is never executed (Based that nothing executes within the callback function and I don't receive errors with bad JavaScript).
In my jsp file:
function getUserText(str)
{
$.getJSON("selectUser.htm", { id: str }, function(user)
{
//Doesn't matter what's here
});
}
In my controller:
#RequestMapping(value="/selectUser.htm")
public #ResponseBody String SelectUser(#RequestParam String id)
{
Users user = userMap.get(id);
if (user == null)
return null;
return createUserJSON(user);
}
I'm not sure about this, but my guess is the function you provide is the success function that gets called when ajax returns. It is possible that the request is not returning successfully.
It means the JSON is invalid. It could be the content is invalid or the content-type is not correctly set....
$.getJSON has no error callback
http://api.jquery.com/jQuery.getJSON/
to see what the problem is you need to use
$.ajax({
url: "myurl",
type: "GET",
dataType: "json",
success: function() {
//called when successful
},
error: function(e) {
//called when there is an error
},
});
Found the answer. Turns out that the JSON needs to be valid. I made a mistake so the JSON wasn't formatted correctly. I didn't know that the format mattered even before the callback function.
My problem happens to be the error, I am attempting to produce an error, in this case the error being hiding the loading symbol and showing a refresh button in order for the user to reload the page to see if the data loads this time.
$(document).ready(function () {
$('#busy').show();
$(document).bind('deviceready', function () {
var today = $('#todaysong');
$.ajax({
url: 'my url',
dataType: 'jsonp',
jsonp: 'jsoncallback',
timeout: 5000,
success: function (data, status) {
$.each(data, function (i, item) {
var song = '<name>' + item.name + '</name>' + '<artist>' + item.artist + '<br></artist>';
$('#busy').hide();
today.append(song);
});
},
error: function (error) {
$('#busy').fadeOut();
$('#reload').fadeIn();
}
});
});
});
This is my code, could someone advise on what I am doing wrong, I've tried a few things and cannot seem to get it to work, also would I make it so said button was able to refresh this individual piece of code?
Thanks a lot.
In order to debug your code:
Are you generating an error on your own? Is it really an error? Track your request via Firebug or ...
Be sure about running the error function. Again try Firebug or such things to set break points.
Check the JavaScript console for being sure there is no any of damn JavaScript error. And again Firebug error console.
Without seeing other details it is difficult to suggest.
Still I'm trying.. Check the IDs of the elements you have mentioned is same as they are in HTML. Check in HTML that one id is not assigned to more than one element.
In the AJAX code remove jsonp: 'jsoncallback', for a while and test if it is working.
error(jqXHR, textStatus, errorThrown)
A function to be called if the request fails. The function receives
three arguments: The jqXHR (in jQuery 1.4.x, XMLHttpRequest) object, a
string describing the type of error that occurred and an optional
exception object, if one occurred. Possible values for the second
argument (besides null) are "timeout", "error", "abort", and
"parsererror". When an HTTP error occurs, errorThrown receives the
textual portion of the HTTP status, such as "Not Found" or "Internal
Server Error." As of jQuery 1.5, the error setting can accept an array
of functions. Each function will be called in turn. Note: This handler
is not called for cross-domain script and JSONP requests. This is an
Ajax Event.
Where the important part in this case is;
Note: This handler is not called for cross-domain script and JSONP
requests.
Quote from the API documentation of jQuery.ajax.
You should instead be using jsonpCallback.