I am trying to use setTimeout to check if data exists in a table:
If the data exists don't fetch data. If the data des not exist fetch the data using load and then do the same thing every x minutes.
Here is what I have so far. For some reason, the setTimeout does not work when it hits the If block.
I am not even sure if this is the best way to do this.
var sTimeOut = setTimeout(function () {
$.ajax({
url: 'CheckIfDataExists/' +
new Date().getTime(),
success: function (response) {
if (response == 'True') {
$('.DataDiv')
.load('GetFreshData/' + new Date()
.getTime(), { "Id": $("#RowID").val() });
}
},
complete: function () {
clearTimeout(sTimeOut);
}
});
}, 10000);
Any help will be greatly appreciated.
Updated ...
setTimeout(function(){checkData()}, 5000);
function checkData(){
$.ajax({
url: 'CheckIfDataExists/' +
new Date().getTime(),
success: function (response) {
if (response == 'True') {
$('.DataDiv')
.load('GetFreshData/' + new Date()
.getTime(), { "Id": $("#RowID").val() });
} else {
$('.OutOfWindow').html('No Data Found');
setTimeout(function () { checkData() }, 5000);
}
},
complete: function () {
// clearTimeout(sTimeOut);
}
});
}
Something like this should work, the first snippet is localized so I could test run it. I've explained the code and below it is what your code should be
Like you realized (from your update on your post) setTimeout only calls your target function once, so to keep checking you need to call it again if you do a check that fails.
See it on JsFiddle : http://jsfiddle.net/jQxbK/
//we store out timerIdhere
var timeOutId = 0;
//we define our function and STORE it in a var
var ajaxFn = function () {
$.ajax({
url: '/echo/html/',
success: function (response) {
if (response == 'True') {//YAYA
clearTimeout(timeOutId);//stop the timeout
} else {//Fail check?
timeOutId = setTimeout(ajaxFn, 10000);//set the timeout again
console.log("call");//check if this is running
//you should see this on jsfiddle
// since the response there is just an empty string
}
}
});
}
ajaxFn();//we CALL the function we stored
//or you wanna wait 10 secs before your first call?
//use THIS line instead
timeOutId = setTimeout(ajaxFn, 10000);
Your code should look like this :
var timeOutId = 0;
var ajaxFn = function () {
$.ajax({
url: 'CheckIfDataExists/' + new Date().getTime(),
success: function (response) {
if (response == 'True') {
$('.DataDiv').
load('GetFreshData/' + new Date().
getTime(), { "Id": $("#RowID").val() });
clearTimeout(timeOutId);
} else {
timeOutId = setTimeout(ajaxFn, 10000);
console.log("call");
}
}
});
}
ajaxFn();
//OR use BELOW line to wait 10 secs before first call
timeOutId = setTimeout(ajaxFn, 10000);
Related
I'm new to javascript, but I can't get my head around this problem. I have a function that upvotes a game:
function upVoteGame(name) {
$.get("/get_gameValues", function(data) {
var alreadyExist = false;
var noVotes = false;
var games;
games = data;
for (var i = 0; i < games.length; i++) {
if (name === games[i].gameName) {
alreadyExist = true;
voteOperations();
if (userLoggedIn == false) {
alert("second");
swal("Cannot post votes", "Please log in or register to vote", "error");
}
if (noVotesLeft == false && userLoggedIn == true) {
$.ajax({
url: '/editVotes/' + games[i]._id,
type: 'PUT',
data: {
likes: games[i].likes + 1,
totalVotes: data[i].totalVotes + 1
},
success: function(result) {
alert(games[i].likes + 1);
}
});
}
refreshGameValues();
break;
}
}
//This is for us Developers!
if (!alreadyExist) {
$.post("/add_game_to_dB", {
gameName: name
}, function(result) {
alert("Introduced " + name);
});
}
});
}
Now I have the function that updates the user's votes left, voteOperations():
function voteOperations() {
$.get("/users/get_current_user", function(data) {
//var votes = 5;
for (var i = 0; i < data.length; i++) {
votesRemaining = data[i].votesRemaining;
userLoggedIn = true;
alert("votes left : " + votesRemaining);
if ((votesRemaining - 1) < 0) {
swal("No votes remaining", "Please wait 24 hours to get more votes", "error");
noVotesLeft = true;
}
if (noVotesLeft == false) {
$.ajax({
url: '/users/updateUserDetails/' + data[i].user_name,
type: 'PUT',
data: {
votesRemaining: votesRemaining - 1
},
success: function(result) {}
});
}
}
});
}
My problem is a simple problem. In the upVoteGame(name) function, I want the voteOperations() to execute before the if loop below it. However, when I run the code, the if loop below executes first and alerts the user that they are not logged in. When a user logs in, userLoggedIn is set to true, but the if loop executes firsts and tells them that they are not logged in, and then executes the voteOperations() function. I don't know why this is happening. How can I fix this so that voteOperations executes before the if loop?
This is because the voteoperations function has a get request which is asynchronous. You will need a callback function where you should include if condition
You can try:
function upVoteGame(name) {
vote(afterGet);
}
afterGet() {
if condition here
}
function vote(callback) {
$.get .... {
//after getting data
callback();
}
}
You problem occurs due to the asynchronous call of your $.get in the voteOperations function.
Since it is an asynchronous call your code continuous while your $.get is waiting to retrieve data and thus your if statement seems to trigger before your voteOperations function.
In simple words your function actually is triggered before the if statement but before it completes it's result the code continues and triggers your if statement.
You could put your if statement (logic) in the success callback of your vote operation function or use $.ajax with async:false which is not considered a good practice generally but I use it sometimes.
Something like that for example (for the second case)
$.ajax({
async: false,
.....
success: function (response) {
//
}
});
Asynchronous calls can be handled with jquery function Deffered
function upVoteGame(name) {
vote().then(doUpVoteGame(), handleError());
}
function doUpVoteGame() {
...
}
function handleError(e) {
console.error("fail", e);
}
function vote() {
var d = new $.Deferred();
$.get .... {
d.resolve();
}).fail(function(e) {
d.reject(e);
});
return d;
}
I have struggled on this topic for a quite a bit of time and it just won't click!
I need to pass the object to the &.post (WordPress processed AJAX) request, but I cannot figure out how to do it correctly using regular variables; instead, I'm forced to call $(document) and iterate over it's DOM elements (very ugly and slow).
How would I correct this code so I'm able to pass the title variable all the way to the post data, instead using $(document).find('#sections_title').val() request?
Please explain how to do this properly.
(function ($) {
var title = $('#sections_title');
var timeout = 2000;
var delay = (function () {
var timer = 0;
return function (callback, ms) {
clearTimeout(timer);
timer = setTimeout(callback, ms);
};
})();
title.keyup(function () {
// i would like to have variable here, that grabs the $(this).val()
// and use this variable to pass to the data
// var value = .......
delay(function () {
$.post(
ajaxurl,
{
'action': 'add_foobar',
'data': $(document).find('#sections_title').val()
// instead I would like:
// 'data': value
},
function(response){
alert('The server responded: ' + response);
}
);
}, timeout);
})();
})(jQuery);
This should be easiest way for your case.
Bind the val as object to callback. Then cast this to string when you need to use it.
delay(function () {
$.post(
ajaxurl,
{
'action': 'add_foobar',
'data': String(this)
// instead I would like:
// 'data': value
},
function(response){
alert('The server responded: ' + response);
}
);
}.bind(Object($(this).val())), timeout);
Or here is the complete code
(function ($) {
var title = $('#sections_title');
var timeout = 2000;
var delay = (function () {
var timer = 0;
return function (callback, ms) {
clearTimeout(timer);
timer = setTimeout(callback, ms);
};
})();
title.keyup(function () {
// i would like to have variable here, that grabs the $(this).val()
// and use this variable to pass to the data
// var value = .......
delay(function () {
$.post(
ajaxurl,
{
'action': 'add_foobar',
'data': String(this)
// instead I would like:
// 'data': value
},
function(response){
alert('The server responded: ' + response);
}
);
}.bind(Object($(this).val())), timeout);
})();
})(jQuery);
You can set it explicitly on the window object. In the browser, the global object is the same as the window object, except for certain environments like node.js.
(function($) {
window.title = $('#sections_title');
var timeout = 2000;
var delay = (function() {
var timer = 0;
return function(callback, ms) {
clearTimeout(timer);
timer = setTimeout(callback, ms);
};
})();
title.keyup(function() {
delay(function() {
$.post(
ajaxurl, {
'action': 'add_foobar',
'data': window.title
},
function(response) {
alert('The server responded: ' + response);
}
);
}, timeout);
})();
})(jQuery);
I am trying to create a block of text that will update itself when the text changes from a Json string.
Basically I started with:
function streamSong(index) {
if (!isUndefined(myPlaylist[index].title))
return myPlaylist[index].title;
else return '';
}
then modified it to look like this:
function streamSong(index) {
var currentSongName = 'here';
if (!isUndefined(myPlaylist[index].title)) {
var intervalFunc = function(){
var jsonData = null;
$.ajax({
url: 'http://www.thesite.com/pullJson.php?stream=rapstation',
dataType: "json",
data: { get_param: 'employees' },
success: function (data) {
currentSongName = 'now here';
},
error: function (data) {
currentSongName = 'not working';
}
});
};
setInterval (intervalFunc, 60000);
setTimeout (intervalFunc, 1);
return currentSongName;
}
else return 'no title';
}
The first function fired off fine and returned my Stream Title.
The second function fires off, but I never am able to modify the value of currentSongName.
I am still a bit new to Javascript and ajax so excuse my ignorance, but I obviously want to ultimately set the value of currentSongName to the Json value I retrieve, but for now I would just like it to be able to change values on a timer.
Am I going about this all wrong?
The variable is modified just fine, but too late. The AJAX call is asynchronous, so the variable is used to return the value before the value is assigned to it.
You would use a callback to handle the result. With the original code it would look like this:
function streamSong(index, callback) {
if (!isUndefined(myPlaylist[index].title)) {
callback(myPlaylist[index].title);
} else {
callback('');
}
}
Usage:
streamSong(42, function(title) {
// do what you want with the title
});
For the AJAX call the callback would be used like this:
function streamSong(index, callback) {
var currentSongName = 'here';
if (!isUndefined(myPlaylist[index].title)) {
var intervalFunc = function(){
var jsonData = null;
$.ajax({
url: 'http://www.thesite.com/pullJson.php?stream=rapstation',
dataType: "json",
data: { get_param: 'employees' },
success: function (data) {
callback('now here');
},
error: function (data) {
callback('not working');
}
});
};
setInterval (intervalFunc, 60000);
setTimeout (intervalFunc, 1);
} else {
callback('no title');
}
}
I'm trying to clear a busy icon and re-enable my delete button once the multiple jquery posts have completed. Here is my current code:
$('#deleteimgs').live('click', function(e) {
e.preventDefault();
if ($('input[name="chk[]"]:checked').length > 0 ) {
$('#deleteimgs').button('loading');
$('#saveicon').show();
var boxes = $('input[name="chk[]"]:checked');
$(boxes).each(function(){
var id = $(this).attr('id').substr(7);
var self = this;
$.post("/functions/photo_functions.php", { f: 'del', imgid: id}, function(data){
if (data.success) {
$(self).hide();
$("#img_"+id).hide(250);
}
}, "json");
});
$('#saveicon').hide();
$('#deleteimgs').button('reset');
}
});
My hide call and reset call are being trigger prior to completion of the foreach loop. Is there a way to wait for completion before making these two calls?
$('#saveicon').hide();
$('#deleteimgs').button('reset');
You should use the success callback method to complete any tasks once the HTTP request has finished. Inside of the callback you should keep track of how many requests have completed, and when your last request has finished, then execute the code of your desire.
You could restructure this code in a few ways, but, it should give you a general idea of how to handle the situation.
var boxes = $('input[name="chk[]"]:checked');
var totalBoxes = boxes.length;
var completedRequests = 0;
$(boxes).each(function(){
var id = $(this).attr('id').substr(7);
var self = this;
$.post("/functions/photo_functions.php", { f: 'del', imgid: id}, function(data){
if (data.success) {
$(self).hide();
$("#img_"+id).hide(250);
//Increment the complete request count.
completedRequests++;
//Check if the last request has finished. If it has, do your stuff!
if (completedRequests == totalBoxes) {
$('#saveicon').hide();
$('#deleteimgs').button('reset');
}
}
}, "json");
});
Try something like :
$(document).on('click', '#deleteimgs', function(e) {
e.preventDefault();
if ($('input[name="chk[]"]:checked').length > 0 ) {
$('#deleteimgs').button('loading');
$('#saveicon').show();
var boxes = $('input[name="chk[]"]:checked'),
xhr = [];
boxes.each(function(){
var self = this,
id = self.id.substr(7);
var request = $.post("/functions/photo_functions.php", { f: 'del', imgid: id}, function(data){
if (data.success) {
$(self).hide();
$("#img_"+id).hide(250);
}
}, "json");
xhr.push(request);
});
$.when.apply(null, xhr).done(function() {
$('#saveicon').hide();
$('#deleteimgs').button('reset');
});
}
});
This will store all the requests in an array that is later passed to $.when, and when they are all done the done() function will be executed.
You need to count the number of posts you make, call an intermediary function to count the replys, then do the hide and reset after all calls have completed.
for example:
var postCount = 0;
function allPostsDone()
{
$('#saveicon').hide();
$('#deleteimgs').button('reset');
}
postCount += 1;
$.post("/functions/photo_functions.php",
{ f: 'del', imgid: id},
function(data)
{
if (data.success)
{
$(self).hide();
$("#img_"+id).hide(250);
}
postCount -= 1;
if (postCount == 0)
{
allPostsDone();
}
}, "json");
To follow up on DwB's answer, using async would be an easy way to supply the intermediary function. instead of:
$(boxes).each(function(){
Use:
async.parallel(boxes.toArray().map(function(elem){
var self = elem;
return function (callback) {
var id = $(self).attr('id').substr(7);
$.post("/functions/photo_functions.php", { f: 'del', imgid: id}, function(data){
if (data.success) {
$(self).hide();
$("#img_"+id).hide(250);
callback();
} else {
callback(new Error("request failed"));
}
}, "json");
}
}), function (err) {
if(err) {
console.log(err);
} else {
$('#saveicon').hide();
$('#deleteimgs').button('reset');
}
});
That should work.
i have an ajax function which gets called and returns json data. this function is called via a setInterval loop:
function SetMaxBidReload() {
var reloadInt = 6000;
var doReload = true;
//set some logic here
if (doReload) {
setInterval(function () { ReloadMaxBid(); }, reloadInt);
}
}
function ReloadMaxBid() {
var nextReload;
$.ajax({
url: 'ajaxcall.aspx',
cache: false,
success: function (data) {
//change to dom elemants here based on return data
nextReload = data[0].NextReload;
}
});
return nextReload;
}
what im trying to do is change the reloadInt of setInterval based on what comes back from the ajax call.
a: is that possible and b: how do i do it?
im open to suggestions on how to accomplish this by coding it differently
setInterval takes the timeout param once and then executes the function based on that interval, changing the reloadInt wouldn't have any effect whatsoever.
You need to use setTimeout in the success callback:
function ReloadMaxBid() {
$.ajax({
url: 'ajaxcall.aspx',
cache: false,
success: function (data) {
//change to dom elemants here based on return data
var next = data[0].NextReload;
if (next !== -1) {
setTimeout(function(){ReloadMaxBid();}, next);
}
}
});
}
You'd also need to use setTimeout with the value of 6000 somewhere to get things started.