
Jquery anchor tag click event does an ajax post, when it redirects, it causes error callback to exec
Question:
My HTML which is at this url '/main/' contains the following link:
<a href="/main/" id="do_something">Do Something</a>
So, the link should do something and then refresh the page.
My jquery looks something like this:
$('#do_something').click(function(event) {
var my_values = ['1','2'];
$.ajax({
url:"/process_values/",
type: "POST",
data: {values:my_values},
success:function(response){
alert("success: " + response);
},
error:function (xhr, textStatus, thrownError){
alert("xhr status: " + xhr.statusText);
},
});
});
The post is executing correctly, but the error callback is always called when it completes.
If I prevent the link from being called using event.preventDefault();, the success function is executed. Why is this? And how do I get the page to update after the post call?
Thanks
Answer1:Without event.preventDefault()
, the user is directed to /main/
(because it's the default behavior of an anchor). Unloading the page causes all pending (XmlHttp) requests to abort, thus triggering the error
function (=request has not finished yet).
An overview:
<ul><li><em>click</em>#do_something
</li>
<li><em>fires</em> click
event -> Ajax request</li>
<li><em>follows</em> link to /main/
.</li>
<li><em>page unloads</em> -> Cancel all requests</li>
<li><em>XHR aborted</em> -> error
function triggered</li>
</ul>If you want the page to open, add this at the success
function:
location.href = "/main/";
Alternatively, if you don't want to hard-code the link:
$('#do_something').click(function(event) {
event.preventDefault();
var linkTo = $(this).attr("href");
var my_values = ['1','2'];
$.ajax({
url:"/process_values/",
type: "POST",
data: {values:my_values},
success:function(response){
alert("success: " + response);
location.href = linkTo; //Redirect the user to the new page
},
error:function (xhr, textStatus, thrownError){
alert("xhr status: " + xhr.statusText);
},
});
});
Answer2:the idea with Ajax is not to do a page reload at all but load data asynchronously (parts at a time)
if you really need to you should use location.reload();
You couold do:
$('#do_something').click(function(event) {
var hrefSaved = $(this).attr('href');
event.preventDefault();
var my_values = ['1','2'];
$.ajax({
url:"/process_values/",
type: "POST",
data: {values:my_values},
success:function(response){
alert("success: " + response);
window.location.href = hrefSaved
},
error:function (xhr, textStatus, thrownError){
alert("xhr status: " + xhr.statusText);
},
});
});
in this way you prevent the default action, make an AJAX call and if the calls is successful redirect to the desired page