Javascript clearInterval() not able to clear the interval - javascript

get_user_record() this function call the method which is pulling data in database. I used time-out because I don’t want response from this method, showUpdatedProgressBar() method which is continuously checking database count and accordingly giving value to progress bar. For that purpose I used setInterval() function which is working but I was not able to clear the interval. Please suggest me where I go wrong.
function get_user_record(){
$.ajax({
url:"/GetData",
type: "GET",
timeout: 2000,
success:function(result){
//alert('success');
},
error: function(xhr, status, err){
//alert('Connection Error. Please try again.')
}
});
var timer = 0;
showUpdatedProgressBar(timer);
}
}
function showUpdatedProgressBar(timer){
$.ajax({
url:"/get_updated_data",
type: "GET",
success:function(result){
result = result.split(',');
var obj = {totalRecords: result[0], recordsTaken: result[1]};
var bar_value = obj.recordsTaken/obj.totalRecords * 100;
$( "#progressbar" ).progressbar({ value: bar_value });
if(obj.recordsTaken == obj.totalRecords ){
clearInterval(timer);
}
else
{
timer = setInterval(function(){ showUpdatedProgressBar(timer) },1000);
}
}
});
}

Previously I defined var timer locally and set to 0
Now it works just by defining var timer; globally and not setting it to zero

timer = setInterval(function(){ showUpdatedProgressBar(timer) },1000);
'timer' is assigned a new interval id with every recursive iteration (it is overwritten). Therefore only the last generated id will be used in clearInterval.

Related

Highcharts: how to stop the function setTimeout when I open new component angular?

if open new component the service of the function setTimeout continue working.
live Demo: http://next.plnkr.co/edit/OqMofEGDadF9J3Uit8qD?utm_source=legacy&utm_medium=worker&utm_campaign=next&preview
//simplified value generator
function requestData() {
$.ajax({
url: 'points.json',
success: function(seriesUpdate) {
//in case initializer of highcharts is too quick - skip the update
if (!chart) {
setTimeout(requestData, 1000);
return;
}
//mocking for making static response data into dynamic
$.each(seriesUpdate, function (serieIndex, serieUpdate) {
mockPointCoordinates(serieUpdate.data[0]);
});
$.each(seriesUpdate, function (serieIndex, serieUpdate) {
var existingSerie = chartSeries[serieUpdate.name];
if (existingSerie ) {
//add a point
var shift = existingSerie.data.length > 20;
existingSerie.addPoint(serieUpdate.data[0], true, shift);
} else {
//add a chart with point
var newSerie = chart.addSeries({
name: serieUpdate.name,
data: serieUpdate.data
}, true);
chartSeries[serieUpdate.name] = newSerie;
}
});
// call it again after one second
setTimeout(requestData, 1000);
},
cache: false
});
}
Store the timeoutID in a global variable (or shared service), and then pass it to a clearTimeout when you need to stop the setTimeout execution.

Timed DOM-updates makes page slow

can anyone help me...my script function automatically updates what's inside the output of my textboxes from the database if I change the values in the table in the database without refreshing the page or clicking the button again to execute the script.
After a seconds later my page is lagy. I can't move my mouse freely. Is there any way how to automatically update data in my textboxes using javascript if I change the values in my table in my database?
current script:
$(document).ready(function(){
var timer ;
$('#send_search_form').click(function(event){
event.preventDefault();
$(".search_form_input").val('');
$(".empty_batchcode").html("Doesn't exist!");
clearInterval(timer);
updateTextboxes();
});
function updateTextboxes(){
$.ajax({
url:"search.php",
type:"GET",
data: { term : $('#query').val() },
dataType:"JSON",
success: function(result) {
var ii = 1;
for (var i = 0; i < result.length; i++) {
$('#funiq_id').html(result[i].value).show();
$('#t_region').val(result[i].region).show();
$('#t_town').val(result[i].town).show();
$('#t_uniq_id').val(result[i].uniq_id).show();
$('#t_position').val(result[i].position).show();
$('#t_salary_grade').val(result[i].salary_grade).show();
$('#t_salary').val(result[i].salary).show();
$('#id'+ii+'').val(result[i].atid).show();
$('#aic'+ii+'').val(result[i].atic).show();
$('#name'+ii+'').val(result[i].atname).show();
$('#other_qual'+ii+'').val(result[i].other_sum).show();
$('#interview'+ii+'').val(result[i].interview_sum).show();
ii++;
}
if(timer == 1){ // if timer has been cleared
timer = setInterval(updateTextboxes,1000); // <-- change 1000 to the value you want
}
}
});
timer = setInterval(updateTextboxes,1000);
}
});
search.php code:
<?php
if (isset($_GET['term'])) {
$q = $_GET['term'];
mysql_connect("localhost", "root", "");
mysql_select_db("klayton");
$query = mysql_query
("
SELECT DISTINCT
ROUND((SELECT SUM(t2.inttotal)
FROM app_interview2 AS t2
WHERE t2.atic = t.atic)/7,1)
AS interview_sum,
ROUND((SELECT SUM(o2.ototal)
FROM other_app2 AS o2
WHERE o2.oaic = t.atic)/7,1)
AS other_sum,
atid,
atic,
atname,
region,
town,
uniq_id,
position,
salary_grade,
salary
FROM app_interview2 AS t
WHERE uniq_id = '$q'
GROUP BY t.atname HAVING COUNT(DISTINCT t.atic) ");
$data = array();
while ($row = mysql_fetch_array($query)) {
$data[] = array(
'value' => $row['uniq_id'],
'atid' => $row['atid'],
'atic' => $row['atic'],
'region' => $row['region'],
'town' => $row['town'],
'uniq_id' => $row['uniq_id'],
'position' => $row['position'],
'salary_grade' => $row['salary_grade'],
'salary' => $row['salary'],
'atname' => $row['atname'],
'other_sum' => $row['other_sum'],
'interview_sum' => $row['interview_sum']
);
}
header('Content-type: application/json');
echo json_encode($data);
}
?>
You are setting more and more setIntervals inside setIntervals and never clearing them. Remember, each setInterval call results in function running multiple times, once every N milliseconds. As the time passes, the amount of running code increases exponentially, which causes lag.
Consider using setTimeout instead. Also, setTimeout or setInterval? might be a good read.
The documentation on the above methods:
https://developer.mozilla.org/en/docs/Web/API/window.setTimeout
https://developer.mozilla.org/en/docs/Web/API/window.setInterval
Two things I have noticed. The first is the setInterval(). Every loop-illiteration it starts another timer. 1sec = 1 interval, 2sec=2, 3sec=4(!), 4sec=8(!!). So after a few seconds, your browser's going crazy. Use setTimeout() instead :)
Number two is saving the DOMreference. Every illiteration you select the id's and set a new value. Every second jQuery finds the elements. It's better to save them first, and then use the saved reference. I've done both:
var $funiq_id = $('#funiq_id'),
$t_region = $('#t_region'),
$t_town = $('#t_town'),
$t_uniq_id = $('#t_uniq_id'),
$t_position = $('#t_position'),
$t_salary_grade = $('#t_salary_grade'),
$t_salary = $('#t_salary');
function updateTextboxes(){
$.ajax({
url:"search.php",
type:"GET",
data: { term : $('#query').val() },
dataType:"JSON",
success: function(result) {
if(result.changedOccured){ // make php send if there are changes (true/false)
var ii = 1;
var resultLength = result.length;// Out of the loop will improve a tiny bit
for (var i = 0; i < resultLength; i++) {
$funiq_id.html(result[i].value).show(); // reference
$t_region.val(result[i].region).show(); // reference
$t_town.val(result[i].town).show(); // reference
$t_uniq_id.val(result[i].uniq_id).show(); // reference
$t_position.val(result[i].position).show(); // reference
$t_salary_grade.val(result[i].salary_grade).show(); // reference
$t_salary.val(result[i].salary).show(); // reference
$('#id'+ii+'').val(result[i].atid).show();
$('#aic'+ii+'').val(result[i].atic).show();
$('#name'+ii+'').val(result[i].atname).show();
$('#other_qual'+ii+'').val(result[i].other_sum).show();
$('#interview'+ii+'').val(result[i].interview_sum).show();
ii++;
}
}
}
}
if(timer == 1){ // if timer has been cleared
timer = setTimeOut(updateTextboxes,1000); // <-- change 1000 to the value you want
}
}
Small note: Saving the DOM references into variables need to happen at the bottom of the page, or on a $(document).ready(). The elements have to exists before you can select them
For better performance, make php send wether or not something has changed. If something has, do the code you have now. If no changes, DONT UPDATE THE ELEMENTS. It's a waste of power to change something from 'abc' to 'abc'.

setTimeout/Interval called from within $.each method?

I am a little confused, I have read from other places that timeout/interval is the best way to make a function in Javascript run every x seconds. I have to make it so that my function runs every 1 second, as this is a rule for the API I'm using.
My code is as follows:
$.each(match_details_json.result.players, function(index, v){
if (v.account_id == 38440257){ //finds desired playerid
var match_id_2 = matches[i];
hero = v.hero_id;
playerpos = v.player_slot;
var kills = v.kills;
var deaths = v.deaths;
var assists = v.assists;
var kda = ""+kills+"/"+deaths+"/"+assists+"";
console.log(match_id_2, hero, playerpos, result, gamemode, kda);
callback();
console.log(match_id_2, hero, result, gamemode, kda);
h=h+1;
setTimeout(get_match_details(h), 10000);
i=i+1;
}
else{
console.log('Not desired player, skipping...');
}
});
Lots of messy code there. But the important part is setTimeout(get_match_details(h), 10000);
Whether that is correct or not, that's me trying to say "Run this function again in 10 seconds" and to continue that, until the each method is finished. It doesn't work.
If necessary, here is my get_match_details function:
function get_match_details(){
$.ajax({
url: 'php/ApiMatchPull.php',
data: {accountid:'38440257', querytype:'GetMatchDetails', querycondition1:'match_id='+matches[h]},
success: function (data) {
console.log ('Match Details were was pulled successfully');
match_details_json = data;
matchdetailsfill(checkvalidity);
}
});
}
Thank you in advance.
This is precisely what setInterval & clearInterval are for.
So instead of setTimeout, you could use it something like :
var timer = setInterval(function() {
get_match_details(h);
}, 1000); // for every second
And when you want to stop it, use:
clearInterval(timer);
You execute the function get_match_details immedatiately, change your code to
setTimeout( function() {
get_match_details(h)
}, 10000 );
What happens in your code is that you loop through all your players and after 10 seconds as many Ajax calls (get_match_details) will be made at the same time.
If you want to have 10 seconds intervals between each ajax call you have to refactor your approach to something like this:
var l = [1,2,3,4,5];
var c = l.length;
var ix = -1;
ajax = function( n ) {
alert( 'do some ajax with ' + n )
}
call = function() {
if( c > ++ix ) {
ajax( l[ ix ] );
setTimeout( function() { call(); }, 1000 );
}
}
call();

Delete localStorage after 1 hour and re-fetch data

I just learned about localStorage and wrote a script to cache the data from an ajax request in local storage.
Can we set a timestamp on the data in localStorage so that after 2 hours it will be deleted and a new ajax request is sent to grab data? This way if the data is updated it, the user can get access to the new data.
Here's a fiddle to my current code to cache the data in local storage.
http://jsfiddle.net/Q77RL/
Here's the code as well:
if ( localStorage && localStorage.getItem('aGithub') ) {
console.log('if statement using local storage');
console.log (JSON.parse( localStorage.getItem('aGithub') ));
}
else {
console.log('else statment using ajax');
$.ajax({
url : 'https://api.github.com/users/paulirish', //just a test because Paul Irisih is awesome!
dataType : 'json',
success : function (data) {
if ( localStorage ) {
localStorage.setItem( 'aGithub', JSON.stringify(data) );
}
console.log(data);
}
});
}
Store an entry in the localstorage that defines the last access time, then compare that to current time each time it is accessed. If n time has passed, get fresh data.
http://jsfiddle.net/Q77RL/2/
var myGithub = {
lifespan: 1*10*1000, //10 seconds, change this to 1 hour
def: $.Deferred(function(def){
if (localStorage && localStorage.getItem('myGithub')) {
def.resolve(JSON.parse(localStorage.getItem('myGithub')))
}
else {
def.resolve({});
}
}).promise(),
fetchData: function(){
console.log(parseInt(localStorage.getItem('myGithubTS'), 10),parseInt($.now(), 10),this.lifespan);
if (localStorage && (!localStorage.getItem('myGithub') || !localStorage.getItem('myGithubTS') || parseInt($.now(), 10) - parseInt(localStorage.getItem('myGithubTS'), 10) > this.lifespan)) {
this.def = $.ajax({
url: 'https://api.github.com/users/paulirish', //just a test because Paul Irisih is awesome!
dataType: 'json',
success: function (data) {
if (localStorage) {
localStorage.setItem('myGithub', JSON.stringify(data));
}
console.log(data);
}
}).then(function(){
return JSON.parse(localStorage.getItem('myGithub'));
});
localStorage.setItem('myGithubTS', $.now());
}
return this.def;
}
};
var counter = 0;
var interval = setInterval(function(){
myGithub.fetchData().done(function(data){
console.log(data);
});
if (counter == 40) {
clearInterval(interval);
}
counter++;
},1000)
The code above will only hit the api once per 10 seconds. Change the lifespan property to change how long the duration is. To get new data, simply use
myGithub.fetchData().done(function(data){
console.log(data);
});
You can use that as many times as you want and it will only hit the api once per 10 seconds.

Preventing a callback from executing until input stops

A timer to fire an AJAX call if no key is pressed. If a key is pressed, then abort the last timer and add a new timer. That is what I want to do but failed to success. Here is my code:
var t;
input.onkeyup = function(){
$('.confirmText').html('Checking...');
var timeStampObj = new Date()
var timeStamp = timeStampObj.getTime();
var oldTimeStamp = $(this).attr('timeStamp');//I store a timeStamp in the element
if(timeStamp < 500 + oldTimeStamp){
$(this).attr('timeStamp', timeStamp);
clearTimeout(t);
}
t = setTimeout(function(){
$.ajax({
url: 'serverScripts/settings/checkEmailAvailability.php',
data: 'email='+email,
success: function(text){
if(text == 'available'){
$('.confirmText').html('Available!');
}else{
$('.confirmText').html('Occupied!');
}
}
});
}, 500);//Half a second
$(this).attr('timeStamp', timeStamp);
}
It sounds like you're asking for a debouncer. The term comes from electronics. It's a way to prevent multiple events from firing within some time threshold. You can use the following function to create a new function that will only be called if a given amount of time has passed since the last event.
function debounce(callback, timeout, _this) {
var timer;
return function(e) {
var _that = this;
if (timer)
clearTimeout(timer);
timer = setTimeout(function() {
callback.call(_this || _that, e);
}, timeout);
}
}
// requires jQuery
$("div").click(debounce(function() {
console.log("tset");
}, 2000));
The callback given to debounce won't execute as long as click events keep firing.
The excellent Underscore.js library includes an equivalent function and there are at least a couple jQuery plugins:
http://code.google.com/p/jquery-debounce/
http://benalman.com/code/projects/jquery-dotimeout/examples/debouncing/
Where do you define the email variable in your JavaScript?
You need to define email somewhere and then check to see if your script works.
var email = $(this).value; // Pseudo-code - are you using jQuery?

Categories

Resources