Checking if jQuery's $.post() failed due to lost connection - post

I do a bunch of $.post()'s in my script, within a $(document).ready(function(){
jQuery says:
If a request with jQuery.post() returns an error code, it will fail silently unless the script has also called the global .ajaxError() method.
I tried adding this as a first test
$(document).ajaxError(function(e, xhr, settings, exception) {
alert('error in: ' + settings.url + ' \\n'+'error:\\n' + exception);
});
But it failed to do anything. Can anyone assist? I just need to popup an alert if the internet connection is lost. I also tried using window.navigator.onLine for this but it's not supported in Safari

have you tried not binding it to document?
$('.log').ajaxError(function(e, xhr, settings, exception) {
alert('error in: ' + settings.url + ' \\n'+'error:\\n' + exception);
});

woops, looks like i managed to loose my association with the original post - i made this post.
Anyway to clarify, the code I have is:
$(document).ready(function(){
$(this).ajaxError(function(e, xhr, settings, exception) {
alert('error in: ' + settings.url + ' \\n'+'error:\\n' + exception);
});
$.post("dostuf.php", { action: "thething" });
No error is being thrown.

Not sure on .post(); but in the api for .ajax() there is an error function you can pass to the object.
$.ajax({
type:"post",
url:"http://yourwebservice.com/get_data",
error:function(XMLHttpRequest, textStatus, errorThrown) {
//do stuff
alert('fail whale');
},
success:function(data) {
alert('it worked!');
}
});
See http://api.jquery.com/jQuery.ajax/
By the way, welcome to stackoverflow!

Related

Handling error in ajax request in Select2

I need to detect if user session is gone when expanding Select2 combobox. When that condition occurs, response is redirected to login page.
The Select2 is populated using an ajax call, so I have added this to the "ajax" parameter:
transport: function (params, success, failure) {
var $request = $.ajax(params);
$request.then(success);
$request.fail(function (jqXHR, textStatus, errorThrown) {
alert(errorThrown);
});
return $request;
}
The problem is that the error reported is not in XHR format (in order to detect 401 HTTP code) but an error telling "SyntaxError: Unexpected end of JSON input".
When seeing the response using Chrome developer tools, I do see that the response was in XHR format with 401 HTTP code but Select2 transforms it in some way.
Is there a way to solve this?
Regards
Jaime
ajax: {
// ...
error: function (jqXHR, status, error) {
console.log(error + ": " + jqXHR.responseText);
return { results: [] }; // Return dataset to load after error
}
}

XML API calling not working with cordova-plugin-advanced-http latest version in ionic3

I am using cordova-plugin-advanced-http plugin for API calling and all JSON enabled API working fine but I have one XML embedded API which is working fine in Postman but while I call it from ionic its param not getting at the server end.
Below is my code for XML API:
Type 1:
let headers = {
"Content-type": 'text/xml; charset=utf-8',
"Authorization": token,
};
let xmlBody =
'<ServiceRequest>' +
'<CaseNumber>' + caseNumber +
'</CaseNumber>' +
'</ServiceRequest>'
this.httpPlugin.setDataSerializer('utf8');
this.httpPlugin.post('https://test.com/Service', xmlBody, headers).then((response) => {
console.log("XML Response : ", JSON.stringify(response.data));
xml2js.parseString(response.data, function (err, result) {
console.log("XML parser success:", result);
console.log("XML parser error:", err);
if (result) {
resolve(result);
} else {
reject(err);
}
});
}).catch(error => {
if (error.status == 403) {
console.log("Token expired : " + JSON.stringify(error));
} else {
console.log("Error : " + error.error);
console.log("Error " + JSON.stringify(error));
reject(error);
}
});
Type 2:
let xmlBody = '<ServiceRequest>' +
'<CaseNumber>' + caseNumber +
'</CaseNumber>' +
'</ServiceRequest>';
console.log("XML Body", xmlBody)
// this.httpPlugin.setRequestTimeout(60);
this.httpPlugin.setDataSerializer('utf8');
this.httpPlugin.setHeader('*', 'authorization', token);
this.httpPlugin.setHeader('*', 'Content-Type', "application/x-www-form-urlencoded");
this.httpPlugin.post('https://test.com/Service', xmlBody, {}).then((response) => {
console.log("XML Response : ", JSON.stringify(response.data));
xml2js.parseString(response.data, function (err, result) {
console.log("XML parser success:", result);
console.log("XML parser error:", err);
if (result) {
resolve(result);
} else {
reject(err);
}
});
}).catch(error => {
if (error.status == 403) {
console.log("Token expired : " + JSON.stringify(error));
} else {
console.log("Error : " + error.error);
console.log("Error " + JSON.stringify(error));
reject(error);
}
});
All the time it's throwing errors from the server and with the same request, I am able to get data in postman as well as Native iOS code.
I referred this issue on GitHub but still no success.
Something I am missing though it's not able to get data on the server.
Help me to solve this issue.
After struggling a lot on this issue I found a solution to clean my request cookies.
In the HTTP Advanced plugin, there is one method to clear my cookies.
clearCookies()
Clear all cookies.
Use this method before calling any API.
So what it will do clear all my cookies and my issue related to old cookies will be solved in this way.
constructor(
public storage: Storage,
public httpPlugin: HTTP,
private platform: Platform
) {
// enable SSL pinning
httpPlugin.setSSLCertMode("pinned");
//Clear old cookies
httpPlugin.clearCookies();
}
The above code solves my issue.
Thanks all for your quick guidance and suggestions.
comment on this if this is not the right way to clear my old request data.

Passing data to Ajax Error block

I have a controller with the following catch statement which returns a partial view and the error to display.
catch (Exception ex)
{
return PartialView("ErrorPartial", new ErrorModel(ex));
}
This controller is being invoked through an Ajax call like this...
$('#myID').ajaxSubmit({
url: buildUrl('MyController'),
beforeSubmit: function () {
toggleOverlay(true, 'Saving...');
},
success: function (responseText, statusText, xhr) {
successSave(responseText, statusText, xhr)
},
error: function (jqXHR, textStatus, errorThrown) {
}
});
If the exception is caught, then the code falls into the error block however I'm unable to pass the partial view data into this.
Is there anyway I can pass the partial data into the error block? If not, could you possibly recommend an alternative?
Thanks :)
You're probably looking for jqXHR.responseText. However, it's not very clear for me why does your js code fail into the error block - you've handled the exception so ajax request should be considered as successfull and success function should be triggered. Here's my C# code which leads to ajax request fail but passes the data along with the error.
Response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
return PartialView("SomePartialView", model);

Phonegap MobileJQuery AJAX Posts Twice while debugging

Hope there is some out there that can help!,
While debugging a WCF service that a phonegap application connects to it seems to post twice.
When the application runs normally no Break points etc it all works fine and i only receive 1.
It appears to me that ajax reposts itself if no response is returned from the server after a few seconds.
I will need to confirm this threw wireshark but just wanted to know if anyone else has come accross this before.
$.ajax({
type: "POST",
url: ServicePATH ,
data: JSON.stringify({ objs: arrayobj, parm2: var2, parm3: var3, parm4: 1 }),
contentType: "application/json",
dataType: "json",
success: function (data, textStatus, jqXHR) {
CallonSuccess(data);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
console.log('error ' + textStatus);
console.log('XMLHttpRequest ' + XMLHttpRequest);
var str = '';
for (prop in XMLHttpRequest) {
str += "prop " + prop + " value :" + XMLHttpRequest[prop] + "\n"; //Concate prop and its value from object
}
console.log(str);
console.log('errorThrown ' + errorThrown);
console.log('passing ' + JSON.stringify({ objs: arrayobj, parm2: var2, parm3: var3, parm4: 1 }));
}
}).done(function () { console.log('Finished ajax'); });
Thanks Lmac
Perhaps no solution (see update below) for you but the same behaviour here.
Without the jquery Mobile framework everything works okay, with the framework embedded it fetches my json file a second time. In Chrome's Console you can see it under Network: GET status 200 and GET status 304 (not modified).
I have the option to throw out jQuery Mobile and I surely will. But would be also interested in knowing what's happening there.
UPDATE:
I had the xmlhttprequest within the $(document).ready(function() { }); It seems as if both jQuery and jQuery Mobile react to that.
If I put the script at the end of the site and make my xmlhttprequest outside the ready-method it fetches my json file only once.

jQuery + Ajax + Loading Spinner Image = Too Fast!

I'm using jQuery in my ASP.NET MVC 2 page. It's a super simple post that gets a date in return. The process itself runs very quickly. I want to use a spinner image to show the user something is going on. All works fine in Firefox, testing locally. However, in IE 8, the spinner image doesn't display long enough; it just flickers. This might confuse the end user if they do not see an indication that the process is working/done. What would be the best way to fix this problem?
Thanks.
<img id="signedout<%: item.Id %>" src="/Content/Images/signed_out.png" alt="Signed Out" title="Signed Out" style="display:none" />
<div id="ajaxloader<%: item.Id %>" style="display:none;text-align:center"><img src="/Content/Images/ajax-loader.gif" alt="loading..." title="loading..." /></div>
<script type="text/javascript">
$(function () {
var id = "<%: item.Id %>";
$("#signout" + id).click(function () {
if (confirm("Are you sure you want to sign this visitor out?")) {
$(this).hide();
//$("#signout" + id).hide();
$("#ajaxloader" + id).show();
var url = '<%: Url.Action("signout") %>';
$.ajax({
type: "POST",
url: url,
data: "id=" + id,
success: function (result) {
$("#timeout" + id).append(result);
$("#ajaxloader" + id).hide();
$("#signedout" + id).show();
$("#row" + id).css("background", "#E8E8E8");
},
error: function () {
alert("There was an unexpected error. Please try again later.");
$("#ajaxloader" + id).hide();
$("#signout" + id).show();
}
});
}
});
});
</script>
It would probably be a better idea to give some other indication that the process has finished rather than misleadingly displaying the spinner when nothing is actually being processed. However you seem set on this.
This is based on amurra's answer and is designed to either hide the spinner once the process is loaded if and only if the timeout has already been returned. Therefore, if the AJAX request returns "too fast" it will wait for the timeout.
var timeoutComplete=false;
var requestComplete=false;
function HideLoadingSpinner() {
if(requestComplete) {
$("#ajaxloader" + id).hide();
} else {
timeoutComplete=true;
}
}
Meanwhile, inside the click handler...
setTimeout(HideLoadingSpinner, 2000);
$.ajax({type: "POST",
url: url,
data: "id=" + id,
success: function (result) {
$("#timeout" + id).append(result);
$("#signedout" + id).show();
$("#row" + id).css("background", "#E8E8E8");
if(timeoutComplete) {
$("#ajaxloader" + id).hide();
} else {
requestComplete=true;
}
},
error: function () {
alert("There was an unexpected error. Please try again later.");
$("#ajaxloader" + id).hide();
$("#signout" + id).show();
}
});
EDIT: I just removed the if(timeoutComplete) stuff from the error function, since there will be an alert before it anyway.
You could set a timeout in js and that would guarantee that the spinner wouldn't be hidden till after the timeout had expired:
function HideLoadingSpinner() {
$("#ajaxloader" + id).hide();
}
Then replace your ajax call with this one:
$.ajax({type: "POST",
url: url,
data: "id=" + id,
success: function (result) {
$("#timeout" + id).append(result);
setTimeout(HideLoadingSpinner, 2000);
$("#signedout" + id).show();
$("#row" + id).css("background", "#E8E8E8");
},
error: function () {
alert("There was an unexpected error. Please try again later.");
setTimeout(HideLoadingSpinner, 2000);
$("#signout" + id).show();
}
});
You could also move the other logic in the success callback into the HidingLoadingSpinner function if you get weird behavior due to the timer.
Can't you just show "Data loaded" message in bright background with fades off in few seconds after reload?
I've seen this before. Actually what you're seeing is IE taking a normal amount of time to run the request and FF taking longer than it should. You can set network.dns.ipv4OnlyDomains to localhost in about:config to dramatically speed up FF on localhost. Source.
In my own applications, I follow #Im0rtality's suggestion and have a notification that an ajax request is complete and show a spinner while it's happening. Many times I don't even see the spinner. I use a custom implementation of JBar for my notifications which is very professional looking.
As far as showing a spinner during AJAX calls, you include this in your master page to show a spinner during all JQuery AJAX calls:
$(function () {
$('.spinner')
.hide()
.ajaxStart(function () {
$(this).show();
})
.ajaxStop(function () {
$(this).hide();
});
});
Then you don't have to include showing and hiding the spinner w/ every call to $.ajax.

Resources