.html() not working in async code - javascript

I have some code sort of like this:
function myFunction(){
$('#somediv').html("Making request...");
$.get('/script.php',
function(data){
if(data.error == 0){
$('#somediv').html("yay!");
} else {
$('#somediv').html("oops!");
window.setTimeout(myFunction(), 2000);
}
},
'json');
}
The "oops!" never displays, I believe possibly because the $.get() request is being called asynchronously. The only way I can make it display is if I wrap it in a window.setTimeout() or run an alert() before it.

Follow your code line by line, and you'll understand what's happening.
function myFunction(){
$('#somediv').html("Making request...");
$.get('/script.php',
function(data){
if(data.error == 0){
$('#somediv').html("yay!");
} else {
$('#somediv').html("oops!");
myFunction();
}
},
'json');
}
$('#somediv').html("Making request...");
$.get()
// waiting for ajax request...
$('#somediv').html("oops!");
$('#somediv').html("Making request...");
steps 4 and 5 are happening within .01 ms most likely, which is why you never see "oops!".
You can use a settimeout around myfunction to make oops visible, but it would likely be better to instead just not display anything so that it just continues to say "Making Request...".

Use:
window.setTimeout(myFunction, 2000);
instead of
window.setTimeout(myFunction(), 2000)
window.setTimeout(myFunction(), 2000); calls myFunction() and it's same with: window.setTimeout(undefined, 2000) because myFunction() returns undefined.
But when myFunction is called you rewrite the html using $('#somediv').html("Making request...");.

Related

ajax call causing fits with hiding a modal

EDIT: Found an un-elegant solution here:
How do I close a modal window after AJAX success
using location.reload(), though I have to say that I think there is a bug in the modal handling in jquery. I do not think my code below was wrong yet it doesn't work. :(
When a user clicks a button it calls a method :
onClick(GroupInformationDialog(true)) ... etc
So that calls a method to see if we should hide or open a modal first based on what is passed and second based on what the result of another method that does an ajax call has:
function GroupInformationDialog(open) {
if (open) {
if (GetProviderInfo() == true) {
$("#groupinfo-dialog").modal("show");
} else {
// we got no real data so let's not show the modal at all
$("#groupinfo-dialog").modal("hide");
}
} else {
$("groupinfo-dialog").modal("hide");
}
return false;
}
and the ajax call:
function GetProviderInfo() {
event.preventDefault();
gid = $('#group_info option:selected').val()
pid = $("#provider_id").val()
$.ajax({
url: '{% url 'ipaswdb: get_group_info_data' %}',
data: "group_id=" + gid + "&prov_id=" + pid,
success: function (resp) {
if (resp['response'] == 'NOGROUP') {
alert("You must first select a group");
$("groupinfo-dialog").modal('hide'); //arg this doesn't work either
return false;
}
else if (resp['response'] == 'OK') {
//fill out form with data.
$("#gi_date_joined_group").val(resp['date_joined_group']);// = resp['credentialing_contact'];
$("#gi_provider_contact").val(resp['provider_contact']);
$("#gi_credentialing_contact").val(resp['credentialing_contact']);
return true;
}
else {
$("#gi_date_joined_group").val('');// = resp['credentialing_contact'];
$("#gi_provider_contact").val('');
$("#gi_credentialing_contact").val('');
return true;
}
}
});
}
The problem is, the return true, or false in GetProviderInfo() is ignored, it is like GroupInformationDialog is evaluated all the way before GetProviderInfo is, so the result is a modal dialog that always pops up.
I even tried to have the
$("#groupinfo-dialog").modal('hide');
in the if(resp['response']=='NOGROUP') code section, with no dice.
It is almost like I need a wait function, I thought success was a call back function was going to take care of it, but alas it did not.
You're mixing synchronous and async code here; you can't synchronously use if (GetProviderInfo() == true) since what you want to return from that function depends on an asynchronous ajax call.
The return statements you currenty have will go to the success handler they're contained within; they will not set the return value for getProviderInfo itself. By the time that success handler runs, getProviderInfo has already returned.
You could have that function return a promise (using return $.ajax({...})) and have the caller handle the results asynchronously -- but it looks like in this case it might be simpler to just hide / show the modal from within the ajax call's success handler. (It looks like the sole reason that isn't working currently is just a typo: there are a couple spots where you have $("groupinfo-dialog") when you mean $("#groupinfo-dialog")

Javascript While or If statement to run a set interval function with

I need a javascript while look that looks for the condition ":visible" on a DOM object and only runs the code when the DOM object is actually visible.
This is my code so far.
if (("#rightPanel").is(":visible") == true){
// It's visible, run fetch on interval!
setInterval(function() {
updateChatField()
}, 500);
} else {
// Do Nothing!
};
What do I need to adjust to get my desired effect? Right now I'm getting ("#rightPanel").is is not a function.
You forgot the $ sign:
if ($("#rightPanel").is(":visible") == true){
// It's visible, run fetch on interval!
setInterval(function() {
updateChatField()
}, 500);
} else {
// Do Nothing!
};
Actually, if I understood correctly, you need the interval to be constantly running so it detects when the element changes to visible. I'd suggest something like:
var $rightPanel; // cache the element
function checker() {
if ($rightPanel.is(":visible"))
updateChatField();
}
function init() {
$rightPanel = $("rightPanel"); // cache
window.setInterval(checker, 500);
}
Then to start it, just call init() after the page has loaded.

Javascript - Get text from html to string

It's a php while with javascript codes. I want that this:
Check every 1 seconds that chat_status.html -text's: status = "offline"
Full code:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
<script type="text/javascript">
// jQuery Document
$(document).ready(function(){
function loadChatStatus(){
var status = ("http://tulyita.hu/chat/chat_status.html".text);
if(status == "offline"){
//this happens 1#
} else {
//this happens 2#
}
}
setInterval (loadChatStatus, 1); //Reload file every 1 seconds
});
</script>
but it isn't worked. :( Can someone help me?
I need the text from the "chat_status.html".
function loadChatStatus(){
$.ajax({
url: "chat_status.html",
cache: false,
success: function(html){
$("#status").html(html); //Insert status into the #status div
},
});
if($("#status") == "offline"){
//this happens #1
} else {
//this happens #2
}
}
??
You can use $.get() to load the contents from your server and do something with it in the callback. Example (not tested):
$.get('http://tulyita.hu/chat/chat_status.html', function (data) {
if (data === 'chat = off' {
// happens when offline
}
else {
// happens when online
}
}, 'text');
Note that the page's current content is chat = off and not offline. Please check the exact contents of data after implementing this in your code.
Also note that your HTML page has to be on tulyita.hu or you have to add an Access-Control-Allow-Origin header because of the same-origin policy.
First, don't declare the loadChatStatus function in .ready() but outside of it. Leave only the setInterval inside the .ready() function. And 1 second is 1000 ms. setInterval expects ms.
Second, use .load() to get the contents of the url, put it in a (hidden) div,and then check what it is. You cannot just do "string".text , as a string has no .text member.

Clear Interval not working ( Tried all other answers )

So I have this function to check when a opponent is connected. Everything works, except the clearInterval thing... I tried adding window.setInterval and window.clearInterval . I tried adding self. too...
$(document).ready(function() {
var waitForOpponent = setInterval(checkUserStatus, 2000);
function checkUserStatus() {
$('#user').load('checkuser.php?randval='+ Math.random());
$("#user").ajaxStop(function(){
if(document.getElementById("user").innerHTML!=""){
clearInterval(waitForOpponent);
opponentConnected();
}
});
}
});
I also tried to go like this:
var waitForOpponent;
function check() { waitForOpponent = setInterval(checkUserStatus, 2000); }
check();
Please help me out guys.. I tried everything...
Get rid of ajaxStop and use the success callback of the .load.
$('#user').load('checkuser.php?randval='+ Math.random(),function(){
if(document.getElementById("user").innerHTML!=""){
clearInterval(waitForOpponent);
opponentConnected();
}
});
if the requests are taking longer than 2 seconds, ajaxstop will never be called.
A better alternative in my opinion is to not use setInterval:
function checkUserStatus() {
$('#user').load('checkuser.php?randval='+ Math.random(),function(){
if(document.getElementById("user").innerHTML!=""){
opponentConnected();
return; // exit
}
setTimeout(checkUserStatus,2000); // continue after 2 seconds
});
}
checkUserStatus(); // start it up
this prevents the ajax requests from piling up on slow connections or on timeouts.

Preventing error 503 on JQuery load

This is my code on shoutbox update :
function updateShoutbox(){
$("#shoutdiv").load("shoutbox.php", { 'action': 'update' } ,
function (responseText, textStatus, req) {
if (textStatus == "error") {
return false;
}
});
}
$(document).ready(function(){
updateShoutbox();
var auto_refresh = setInterval(
function ()
{
updateShoutbox();
$("#shoutdiv").scrollTop($("#shoutdiv")[0].scrollHeight);
}, 6000);
It returns error each some minutes :
shoutbox.php returned error:
Service Unavailable
Is there anyway to handle this error and hide it somehow ?
I edited my code so to stop showing any error on shoutbox update, but it still shows this error each minutes.
Ok, so let's take this for example:
$(document).ready(function(){
(function iterate(i) {
if (!!i) {
console.log('iteration #', i--);
setTimeout(function next(){
iterate(i);
}, 1000);
}
})(10);
});​
http://jsfiddle.net/userdude/6C8yp/
If you look at the console, you'll see it counts down until i is equal to 0, or i is not given (that's what the !! is for there). What I'm doing here is looping each second, but only after the last loop has finished. I'm feeding my loop.
Looking at what you have here, I might do this instead:
$(document).ready(function($){
var $shoutbox = $("#shoutdiv"),
timer;
(function update(){
var opts = {
url: 'shoutbox.php',
action: 'update',
complete: wait
};
$.ajax(opts);
function wait(res, status, req){
if (status == 200) {
$shoutbox
.append(res)
.scrollTop($shoutbox[0].scrollHeight);
timer = setTimeout(update, 6000);
}
}
})();
});​
http://jsfiddle.net/userdude/whsPn/
http://jsfiddle.net/userdude/whsPn/1/
Ok, so what we have above should mostly emulate the code you have in the question. You'll note that I have the complete: wait part in there, and the setTimeout() is in that callback. And.. it's only called if the status returned is 200 (success).
Now, there you could turn complete: wait to success: wait, and take out the status == 200 if statement altogether. Of course, if you do want to run the update again, but maybe do something different, this is your chance.
Also note, in the fiddle linked I've got some dummy code in there. So don't just copy/page what's in the fiddle, or you'll have errors and it won't run at all.
EDIT: Oops, found an error with url =. Fixed.
If you want to "hide" your error instead of looking for the cause of the error in the first place, try this in your callback function in the $.load:
function (responseText, textStatus, req) {
if(req.status!=200&&req.status!=302) {
return false;
}
//update the shoutbox
}
At least to me this is what seems to be the most reliable way to prevent random errors from getting through your checks.

Categories