clearInterval and setInterval in javascript Instantly - javascript

<script>
Main Function:
var interval;
function refreshId(session_to_user) {
interval = setInterval(function()
{
$('.chat-box').load("<?php echo base_url()."users/message/refresh_div/"; ?>" + session_to_user);
}, 10000);
}
in this main function I'm only going to perform my requirement here. I have a variable interval my enabling this function, and it will refresh every 10 seconds.
onclick of function
forloop
{
<a href = "" onclick="myFunction(user_id)"
}
function myFunction(user_id){
clearInterval(interval);
$.ajax({
success:function(data)
{
$('.chats').html(data);
}
})
refreshId(session_to_user);
}
If anyone clicks on href, it should clearInterval if already exists else a new Interval has to be established on click function. In my current code, it works if I click for the first time. It starts refreshing the first link for every 10 seconds, but when I click for the second time on the second link, it waits. Still, the first one gets executed and then the second one is executing. My requirement is if I click, the established setInterval has to stopped instantly and the new one has to be started on the spot same as for my next function paper_plane() also.
function paper_plane()
{
clearInterval(interval);
$.ajax({
success:function(html)
{
$('#chat').append(html);
$('.chat-input').val('');
$('.chat-input').focus();
}
});
}
var side_bar_path = "<?php echo base_url()."users/message/load_side_bar"; ?>";
$.ajax({
success : function(data)
{
$('.msg-list').html(data);
}
});
refreshId(session_to_user);
}

There is no way you can cancel the ajax request after the delay(10 seconds) is elapsed from first click handler,since it would not return the result immediately.
so the only way you can cancel the previous ajax calls before making a new ajax call is to suppress/ignore the responses of the previous ajax calls once the second link is triggered, this way you will create a scenario what your expecting.
Below i have created a small snippet which will do the scenario mentioned above.
JS Code:
var firstTimer;
//first click handler
$('#first').on('click',function () {
firstTimer= setInterval(function (){
$.ajax({
url:"http://target.org/page.html",
dataType: "POST",
data:{'name1':'davy'}
success: function(data) {
//suppress the response when timer is stopped.
if(firstTimer>0){
return;
}
//if timer is not stopped process the data
},
error :function(error) {
//handle error
}
});
},1000);
});
//second click handler
$('#second').on('click',function () {
//clear the firstTimer before staring a new timer
clearInterval(firstTimer);
var timer;
timer = setInterval(function (){
$.ajax({
url:"http://target.org/page2.html",
dataType: "POST",
data:{'name1':'rog'}
success: function(data) {
//process the data
},
error :function(error) {
//handle error
}
});
},1000);
});

Related

Is JavaScript clearInterval asynchronous?

I have the code below.
var intervalId;
function myCallback() {
$.ajax({
url: "http://bla.html",
cache: false,
success: function(data) {
if (intervalId) {
clearInterval(intervalId);
}
if (data && data.result) {
return;
}
alert(data.result);
}
, timout: 2000
});
}
function callInterval() {
intervalId = setInterval(myCallback, 5000);
}
callInterval();
The problem is that the "clearInterval(intervalId)" doesn't seems to invalidate the interval at this right time because the message alert is shown twice.
So here is my question, is clearInterval(intervalId) asynchronous?
The point is not about being the clearInterval sync or async.
In your code you start the interval the first time, and then after every second you execute your myCallback.
Clearing the interval when you get back a response, means that during the time that the ajax request is performing, the interval is still running and will start new ajax requests.

delay for not running other lines of code

in this code i want to when div with .ch1 class changed background to answer_box_small_orange.png other bottom js lines code don't run and no ajax request sends until 3 seconds and i used
window.setTimeout(function () {}, 3000)
but it doesnt work correctly
here first of all i request and get data and it is ok
$.ajax({
type:'post',
url:'http://207.154.251.233:8039/app.php/question/get',
data:JSON.stringify({apikey:'jwebdpqodp9fgkwjebfkdpqihdqlwkndqp'}),
success:(function (response) {
var x = response;
$("#question").text(x.result.question);
$(".op1").text(x.result.options["1"]);
})
});
i inserted ajax code and some other codes in function because i want to run it every 60 seconds
function myInterval () {
$(".ch1").css('background-image','url(image/answer_box_small.png)');
var clock;
$(document).ready(function() {
clock = new FlipClock($('.clock'), 60, {
clockFace: 'Counter',
autoStart: true,
countdown: true,
callbacks: {
stop: function() {
$('#loading').fadeIn('5000');
$.ajax({
type:'post',
url:'http://79.175.166.98/',
data:JSON.stringify({apikey:'jwebdpqodp9fgkwjebfkdpqihdqlwkndqp'}),
success:(function (response) {
$('#loading').fadeOut('slow');
var x = response;
$("#question").text(x.result.question);
$(".op1").text(x.result.options["1"]);
var answer = x.result.answer;
if(answer == 1){
$(".ch1").css('background-image','url(image/answer_box_small_orange.png)');
}
window.setTimeout(function () {}, 3000);
})
});
}
}
});
});
}
myInterval();
window.setInterval(function(){
myInterval();
}, 60000);
Based on what you told me, my interpretation is that you have a setTimeout() function and a setInterval() function. The setTimeout() runs at the beginning and will wait for 3 seconds. Then call an ajax function to create new requests every 6 seconds. Your problem seems to be that your first setTimeout() is re-run after you create your first AJAX request, but you want it to stop.
Taken from W3
setTimeout Return Value: A Number, representing the ID value of the timer that is set. Use this value with the clearTimeout() method to cancel the timer.
Knowing this, we can essentially cancel a setTimout() function. In your case, the first setTimeout().
Consider this,
var firstIntervalID = setTimeout(function() {
$.ajax() {
// First AJAX ran after three seconds.
}
}, 3000);
clearTimeout(firstIntervalID);
// Your code resumes to set an interval every 60 seconds without having to worry about the three seconds set before
myInterval();
var secondIntervalID = setInterval(function(){
myInterval();
}, 60000);
Essentially, you cancel the setTimeout() when you don't need it anymore. Your application for it can be different than what I wrote, but the main idea is the same. Cancel/Clear the setTimeout() with the ID that is returned on setTimeout() with clearTimeout().

Replaced timeout event fires twice or more (sometimes)

I have a section of content that allows a user to edit it upon double-clicking on it. If the user changes the content and then stops for 2 seconds, the updated content is sent to the server to be saved.
To do so, I have bound an input event listener to that section that starts a 2 seconds countdown, and if there is already a countdown, the former will be cancelled and a new one will start instead. At the end of the countdown an http POST request is sent to the server with the new data.
The problem is that sometimes at the end of the countdown I see 2 or more requests sent, as if a countdown was not cancelled before a new one was inserted, and I can't figure out why.
The code in question is as follows:
//this function is bound to a double-click event on an element
function makeEditable(elem, attr) {
//holder for the timeout promise
var toSaveTimeout = undefined;
elem.attr("contentEditable", "true");
elem.on("input", function () {
//if a countdown is already in place, cancel it
if(toSaveTimeout) {
//I am worried that sometimes this line is skipped from some reason
$timeout.cancel(toSaveTimeout);
}
toSaveTimeout = $timeout(function () {
//The following console line will sometimes appear twice in a row, only miliseconds apart
console.log("Sending a save. Time: " + Date.now());
$http({
url: "/",
method: "POST",
data: {
action: "edit_content",
section: attr.afeContentBox,
content: elem.html()
}
}).then(function (res) {
$rootScope.data = "Saved";
}, function (res) {
$rootScope.data = "Error while saving";
});
}, 2000);
});
//The following functions will stop the above behaviour if the user clicks anywhere else on the page
angular.element(document).on("click", function () {
unmakeEditable(elem);
angular.element(document).off("click");
elem.off("click");
});
elem.on("click", function (e) {
e.stopPropagation();
});
}
Turns out (with help from the commentators above) that the function makeEditable was called more than once.
Adding the following two lines of code at the beginning of the function fixed the issue:
//if element is already editable - ignore
if(elem.attr("contentEditable") === "true")
return;

jQuery clearTimeout on ajax success is getting confused and not clearing previous timeouts

I have a form submitted by jQuery ajax which has error validation server side. On beforeSend I show
a gif loader and some loading text and when validation is send back on success method I show the appropriate messages for error.
This messages have timeout to hide after x seconds. Anyways when i continue clicking the submit button,
setTimeout is confusing itself and previous ones are not clearing. Here is the code I am using:
EDIT
$('form').on('submit', function(e) {
e.preventDefault();
var timer = null;
$.ajax({
beforeSend; function() {
$('.response').html('Processing form, please wait...');
},
success: function(data) {
if(data.error == true) {
$('.response').html('An error occurred.');
} else {
$('.response').html('Thank you. Form submitted successfully.');
}
if(timer) { clearTimeout(timer) };
timer = setTimeout(function() {
$('.response').html('* Indicates required fields.');
}, 10000);
}
});
});
Any suggestions appreciated.
The timer variable is scoped to your success function, so it's always null when your code to clear the old timeout is reached. Move the declaration of timer outside your AJAX call, and it should work.
var timer = null;
$.ajax({
beforeSend: function() { ... },
success: function(data) {
if(timer) { clearTimeout(timer) };
timer = setTimeout(myfunction, 10000);
}
});

Checking the content of div with jquery

In my project, I have a channel which displays videos at scheduled times. When there is not video at a time, in the place of div for displaying video, it will show an image with ID pgmimg.
<img id="pgmimg"/>
For implementing this feature I am calling a setInterval() which will check the current content in the video div. If it is the default image, then it will call an ajax function which will check whether there is any video at this time. If there is, then it will send the response.
$(document).ready(function() {
if ($('#pgmimg').length) // checking for next video only if there is no any video playing, ie., if the default image class is present
{
setInterval(function() {
nextchannel('<?php echo base_url();?>')
}, 3000);
}
});
function nextchannel(baseurl)
{
$.ajax({
type: 'post',
datatype: 'html',
url: baseurl + 'index.php/index/nextvideo',
success: function(response)
{
$('.videoarea').html(response);
}
})
}
PHP
function nextvideo()
{
$currentpgm = $this->db->query("query for fetching current programme");
$pgm = $currentpgm->row();
$currentpgnnum = $currentpgm->num_rows();
if ($currentpgnnum > 0)
{ // if there is any program at current time then display the video
echo '
<input type="hidden" name="starttime" id="starttime" value="' . $pgm->starttime . '"/>
<input type="hidden" name="currentdate" id="currentdate" value="' . $currentdate . '"/>';
}
else
{ // if there is no video, then show the default image with id pgmimg
echo '<img src="'.base_url().'images/video_sample.png" alt="video" id="pgmimg"/>';
}
exit;
}
Now the problem is that, it failed to check whether default image id is present or not (call setInterval only if default image id is present in the webpage) in the setInterval function $('#pgmimg').length. The video is playing,
but the setInterval() function is again getting called. But that should not happen.
Can anyone help me to fix this?
Thanks in advance.
Instead of setInterval use recursive setTimeout calls, so you can stop polling when needed. The added benefit of polling with setTimeout is if for some reason it takes longer than 3 seconds to get a response, you don't start making overlapping requests.
$(document).ready(function() {
if ($('#pgmimg').length) // checking for next video only if there is no any video playing, ie., if the default image class is present
{
setTimeout(function() {
nextchannel('<?php echo base_url();?>')
}, 3000);
}
});
function nextchannel(baseurl)
{
$.ajax({
type: 'post',
datatype: 'html',
url: baseurl + 'index.php/index/nextvideo',
success: function(response)
{
$('.videoarea').html(response);
if ($('#pgmimg').length) // call again if necessary
{
setTimeout(function() {
nextchannel('<?php echo base_url();?>')
}, 3000);
}
}
})
}
You need to do the test when the interval function runs, not when you're initially scheduling it:
$(document).ready(function() {
setInterval(function() {
if ($('#pgmimg').length) {
nextchannel('<?php echo base_url();?>');
}
}, 3000);
});
You did not clear the interval, so it gets called on and on.
Just save the interval to a variable:
var interval = window.setInterval(function() {
// check for the div
if($('#pgmimg').length > 0) {
nextchannel(url);
}
}, 3000);
function nextchannel(baseurl) {
// ajax ... success:
window.clearInterval(interval);
}
You are trying to implement wrong logic you need to implement
if($('#pgmimg').length > 0 )
I think this will solve your problem

Categories

Resources