Signaling periodic ajax call to terminate - javascript

I have an onclick event for a radio button that calls a function which launches period AJAX calls to some url
Example in MVC cshtml view
<script>
function onClick(selectedRowId) {
GetData("/home/GetData/" + selectedRowId);
};
</script>
Ajax call
function GetData(url) {
$.ajax({
url: url,
type: "GET",
cache: false,
contentType: "application/json; charset=utf-8",
success: onSuccess,
error: onError,
complete: function (xhr, status) {
setTimeout(function () {
GetData(url);
}, 10000);
}
});
}
When a different radio button is selected I need to call the onClick method with the selected radio button id and this again initiates a call to the url with the different id.
However, I would like the previous AJAX function call to terminate since the AJAX onSuccess method updates an html element with the data retrieved for that specific selected Id.
Any way to signal the previous call to terminate before launching new one ?
One way to solve this could be
a) Not make id as a paramter to the url call then
b) in the onClick method send a call to Server to set the Id variable (this makes the server aware that all data must be returned for that Id)
c) Then ensure that ajax function is called only once and server will change data returned based on Id information conveyed to it in (a)
Not sure if the server round trip is worth it here for every button click.

The best I can think is each time onClick fired, it needs to cache the selectedRowIndex which you are only interested in the latest selected one. As you mention, the server need to return that ID back. That way on your onSuccess function, you only need to process returns that matched ID and ignore any other.
I don't think you can literally stops previous ajax. You don't have access to the previous ajax object any more. Just ignore previous responses.

Related

Laravel request()->ajax() triggering on browser back button

Inside my controller I have this function for the route /backups
public function index()
{
$backups = \App\Backup::all();
if(request()->ajax()) {
return $backups;
}
return view('backups.index', compact('backups'));
}
My idea was that if I have my javascript ask for the data then return json if not return html.
This works fine, except when pressing the browser back button to go from lets say /backups/1 to /backups it shows the json.
Is there another function I can use that will only respond to ajax calls from my code and not the browsers?
I'd recommend adding an ajax-only query string parameter to the ajax request, e.g. ?ajax=1.
This way, you can 1. utilise the browser cache, and 2. keep the same Laravel route for both request types.
Make sure your AJAX requests use a different URL from the full HTML documents. Chrome (and most probably Firefox) caches the most recent request even if it is just a partial.
Source:
https://code.google.com/p/chromium/issues/detail?id=108425
Or:
Try setting cache to false
$.ajax({
dataType: "json",
url: url,
cache: false,
success: function (data) {...}
});

JQuery - Send inputs via ajax (which were obtained by ajax)

I have an application that after performing a search, returns me multiple "fieldsets" with some hidden inputs (via AJAX!).
I want to use these inputs to send information to the server (again) via AJAX.
The names of these inputs are automatically listed with a prefix:
"video_url_1", "video_url_2", etc.
When the user clicks the button, the value of "video_url_1" or "video_url_2" will be sent via AJAX depending on the button to which it has clicked. To solve this I got the name of the button that was clicked and then I cut the name so that I only have one number, this number I put in a variable and then use it in the "data" section of AJAX.
I did the test by sending a locally stored input and it worked but when trying to send the inputs that were previously obtained by an ajax, it does not work.
What can be wrong? This is my code:
$(document).ajaxComplete(function(){
$('a.report_video').click(function() {
var idbutton = $(this).attr('id');
var idreport = idbutton.replace('report_video_', '');
//I'm still not using these variables, can they be used to pass the input data to ajax?
var videourl = $("#video_url_" + idreport).val();
var videoid = $("#video_id_" + idreport).val();
var videoserver = $("#server").val();
///////////
$.ajax({
type : 'POST',
url : 'https://example.com/script/script.php',
data : $($("#video_url_" + idreport)).serialize(), //It doesn't work
//For example, data: $("#server").serialize()
//Work fine, this input is stored locally.
beforeSend: function(){
$('#video_report_' + idreport).html('<img src="'+pluginUrl+'./assets/img/loading.svg" />');
}
}).done(function(data) {
$('#video_report_' + idreport).html(data);
});
return false;
});
});
Edit:
I just did some tests as suggested by Kevin B and I see that the problem I have is in the syntax when trying to send two dynamic ID's by Ajax.
The problem is that I do not know how to write them correctly, I know that is the problem because when I tried to send them separately they did work...
data : $($("#video_id_" + idreport), $("#video_url_" + idreport)).serialize(),
I'm not sure I completely understand your problem, but this might help.
You call your second AJAX call in the .success() method of the first AJAX call. Essentially chaining the responses.
$('#btn').click(function() {
$.ajax({
type: "POST",
url: 'someURL',
data: someData
}).done(function(firstCallData) {
// This OPTIONAL method fires when the AJAC call succeeded
// You can also put another AJAX call in here with the data returned from the first call
$.ajax({
type: "POST",
url: 'someURL',
data: firstCallData
}).done(function(data) {
// Do something with second AJAX call with data
}).fail(function(data) {
// Second AJAX call failed, handle error
});
}).fail(function(data) {
// This OPTIONAL method fires when the first response failed
}).always(function(data) {
// This OPTIONAL method fires regardless if the first call succeeded or failed.
});
});

How to cancel MVC action if I use AJAX to call it?

I have an AJAX function on a view that calls an Action on one of my controllers to get a JSON object. The problem is that it takes a while to create the object. If the user reloads the page, then the AJAX call runs again. As far as I can tell the action is still running from the last request, but the response is no longer relevant because the new AJAX call is waiting for the new response.
My question is, how do I keep the action from continuing if the user leaves the view that called it?
Ajax:
$.ajax({
type: "get",
url: "/Alert/GetWallboardAlerts",
cache: false,
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (result) { ... }
});
Controller action:
public ActionResult GetWallboardAlerts()
{
//...do long running stuff
//...still doing stuff when page reloaded or I navigate elsewhere
return Json(alertString, JsonRequestBehavior.AllowGet);
}
I don't think you can. Once you made a request to the server, you could close the browser but the request will still be executed.
This is just an idea:
1) Caller makes an AJAX request and provides a unique value (could be a guid).
2) Handle the page reload event and the close event and send a new AJAX request with the same unique key requesting a cancellation.
3) The long process task that is executed on the server should check for a flag that indicates that the task has been canceled.
You could also use a WebSocket for a task like this so the server could ping the client (like a "still alive" request). If you are using .NET you could use SignalR.
I hope it helps or at least it gives an idea to solve your problem.

Efficient way of passing data and calling background script in PHP

I have a page where I show 5 questions to a user and when he clicks on Next 5 link I am sending the score of current page onbeforeunload() to the script updateScore() asynchronously using jQuery AJAX and when the call is successful the next 5 questions are displayed.
window.onbeforeunload=function()
{
$.ajax({
type: "POST",
url: "updateScore.php",
data: "pageScore="+score,
cache: false,
timeout:5000,
async:false
});
}
But the problem is that on slow connections,it might hang the browser for a while until AJAX call returns successfully.When I tried async:true(default) the next page is loaded first without making call to updateScore.php.It might be due to the fact that connection is fast in localhost hence giving no time for the AJAX call to complete.This was the reason I used async:false.Will it happen (making no AJAX call) if I use async:true in practical case as well?If yes, is there a way to come around this problem?
I advice you to change your code a bit.
Make ajax request on "click" event, and redirect user inside ajax callback function.
Like this:
$('#mybutton').on('click', function()
{
$('#pleasewait').show();
$ajax({
type: "POST",
url: "updateScore.php",
data: "pageScore="+score,
success: function() { document.location="nextpage.php" }
});
}

How can I be sure my Ajax call has fully completed?

I have the following code:
$.ajax({
cache: false,
url: "/Administration/" + entity + "s/Update",
data: { pk: pk, rk: rk, fld: type, val: val },
success: function () {
disableLoadingIcon();
if (idArr.substr(0, 8) == 'Position') {
location.reload();
}
}
});
When a user changes some data the code updates the database. There is code that comes before this that picks the data values and it all works good.
When the user changes the Position column the database gets changed and I wanted to trigger a refresh of the screen (it's a report screen sorted by position). The refresh works but it seems like it is out of sync. I have the location.reload() in the success area but is it possible that is getting run before the Ajax has completed?
Is it possible that this kind of refresh is taking place before the database has been properly updated? When I do another refresh of the page manually from the browser the data always appears in the correct order.
Your document is cached. You shouold use
location.reload(true)
to realod with clear cache.
AJAX is asynchronous by default. Once the call is issued, the rest of your code will continue executing. If the value of location gets changed before the ajax call returns its data, the success function will be using the current-at-the-time-it-executes value of location, which is now something different than what it was when the ajax call started.
The success code will not run until the ajax call returns, so that's not the problem. but you're depending on location not being changed between the time you start the ajax stuff and the time it completes.
there is a API in jquery ajaxComplete. whenever a ajax call will be completed this will be invoked.
$.ajaxComplete(function(){
//do something
});
reference : http://api.jquery.com/ajaxComplete/
Whatever you write inside the success handler will be executed only after the completion of the ajax request you made to the server page. so you can load the updated content in that handler.you can use a parameter to accept the response from your success function and check whether your transaction is success or not.
From your server page, after making the database update,you can return true or false.
$.ajax({
cache: false,
url: "/Administration/" + entity + "s/Update",
data: { pk: pk, rk: rk, fld: type, val: val },
success: function (data) {
// This will be excuted only after you receive a response from your server page
if(data=="true") //db updated properly
{
disableLoadingIcon();
if (idArr.substr(0, 8) == 'Position') {
location.reload();
}
}
else
{
alert("Error in updating the data");
}
}
});

Categories