Is it possible to have multiple ajax calls on the same page, at the same time to different receiving div tags? I am struggling with finding answer to this.
I have 3 pages. A home page and 2 php pages: status and alert pages echoing the results.
Inside the home page I have 2 divs that get their data changed using ajax.
<div id="statusTable"> </div>
<div id="alertsTable"> </div>
Using setInterval I make 2 requests for new data for the divs at the same time. My problem is that both divs have the same data in them once the call is made - it's as if only one call was made for both.
setInterval
(
function()
{
getAlerts();
getStatus();
},
1000
);
I get this eg.
alerts table // getStatus() call
2 2
2 2
status table // getStatus()
2 2
2 2
instead of
alerts table //getAlerts()
1 1
1 1
status table //getStatus()
2 2
2 2
This is the code:
function loadXMLDoc(url,cfunc)
{
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=cfunc;
xmlhttp.open("GET",url,true);
xmlhttp.send();
}
function getAlerts()
{
loadXMLDoc("alerts.php?update=variable",function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("alertsTable").innerHTML=xmlhttp.responseText;
}
});
}
function getStatus()
{
loadXMLDoc("status.php?update=variable",function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("statusTable").innerHTML=xmlhttp.responseText;
}
});
}
I changed the timer setIntervals so the calls don't overlap the data received in the divs like below
setInterval
(
function()
{
getAlerts();
},
5000
);
setInterval
(
function()
{
getStatus();
},
3000
);
I am hoping there is a way to make a call at the same time and not have to worry about my divs having the same content.
First, AJAX uses HTTP protocol which is stateless. If you can't be sure which answer reached first unless you tag them yourself in the response body.
Maybe the 2 reaches first and set, as receiving only one packet results in readyState change and drops other.
Your xmlhttp variable is defined globally. So by that, the packet with 1 inside is overloaded by packet with 2 inside. Try using var xmlhttp while defining it in your getAlert and getStatus functions and provide it to your loadXMLDoc function as a parameter.
Second, make sure whether the results should be different or not. Maybe it is just a coincident that both values are the same.
You need to decalre the xmlhttp variable locally in loadXMLDoc()
function loadXMLDoc(url,cfunc)
{
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=cfunc;
xmlhttp.open("GET",url,true);
xmlhttp.send();
}
Without doing this, the xmlhttp value that is improperly declared in the function "leaks" into the global scope, meaning that you end up overwriting the values with whichever is called second (including the url value set on the object). You in essence introduce a race condition into your code due to asynchronous nature of the calls.
The race condition and the xmlhttp being global are the problems here.
What ever came last is overwriting the data written in the divs. Solve it by making xmlhttp variable
local as per suggestions and tagging the response body.
function loadXMLDoc(xmlhttp,url,cfunc)
{
xmlhttp.onreadystatechange=cfunc;
xmlhttp.open("GET",url,true);
xmlhttp.send();
}
function getAlerts()
{
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
loadXMLDoc(xmlhttp,"alerts.php?update=variable",function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200 && xmlhttp.responseText.indexOf("unique key") != -1)
{
//change div which matches unique key
}
});
}
Credit: #Mike Brant and #Cunning
Before people like me want to continue and use more ajax calls check out
how browsers handle and process multiple ajax calls:
How many concurrent AJAX (XmlHttpRequest) requests are allowed in popular browsers?
http://sgdev-blog.blogspot.com/2014/01/maximum-concurrent-connection-to-same.html
Related
What I am trying to do is to make two ajax calls and make each result show up in two different divs of the same page.
Here is my Javascript code:
function firstLoad(){
firstDiv(datedisplay.value);//populating first div
secondDiv(datedisplay.value);//populating second div
}
function loadXMLDoc(url,cfunc){
if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=cfunc;
xmlhttp.open("GET",url,true);
xmlhttp.send();
}
function firstDiv(changed_date){
var divided_date = changed_date.split("-");
loadXMLDoc("getmonth.php?m="+divided_date[0]+"&y="+divided_date[1],function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200){
document.getElementById("timetableview").innerHTML=xmlhttp.responseText;
}
});
}
function secondDiv(changed_date){
var divided_date = changed_date.split("-");
loadXMLDoc("getmonthexp.php?m="+divided_date[0]+"&y="+divided_date[1],function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200){
document.getElementById("expensesview").innerHTML=xmlhttp.responseText;
}
});
}
The response content is correct, however what happens now is that:
The second div is filled correctly.
The first div stays in blank, and if I keep refreshing the page, eventually the content of the second div will show up in the first div as well(weird).
Hope you guys can help me.
xmlhttp is global because you don't use the var keyword. This means that the onreadystatechange function you use for one will overwrite the other.
function loadXMLDoc(url, cfunc) {
var xmlhttp;
xmlhttp is global because you don't use the var keyword. This means that the onreadystatechange function you use for one will overwrite the other.
function loadXMLDoc(url, cfunc) {
var xmlhttp;
I have searched but cannot find an answer to this issue. I am calling an asynchronous javascript file and the php page it calls makes a database entry twice.
window.onload = function(){
var xmlhttp;
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else {// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
alert(xmlhttp.responseText);
//document.write(xmlhttp.responseText);
return;
}
}
xmlhttp.open("POST","http://example.com/api/tracking/index.php?cid=" + get["clientId"] + "&refUrl=" + encodeURIComponent(siteURL) + "&auk=" + get["auth"],true);
xmlhttp.send();
}
The index php page does an insert and returns the new row id. The alert in the successful response corresponds to that id, but there is another entry made one millisecond before. I assume this is happening because the page is being accessed until it gets the ready state of 4. The question is how do I stop or bypass this?
So I have some code, which checks for whether a one time use discount code exists, and if so, it applies it and then marks it as used in the database. The problem is, it ends up being useable more than once if you spam click it, and then some time maybe 15-20 seconds later it stops being useable.
The relevant javascript component:
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
} else { // code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
discountAmount += parseFloat(xmlhttp.responseText);
modifyCartOrder();
}
}
xmlhttp.open("GET","forms/jsPromoCode.php?code="+code+"&type="+order_name,true);
xmlhttp.send();
This is processed over in the php file, and when a match is found we echo that amount and then delete the entry
$mysqli->query("DELETE FROM discounts_available WHERE `index`=$index");
The php file is indeed doing what its supposed to. When you click apply code, it is immediately deleted from the database. The problem is, even with the code no longer in the db, you can still apply the code over and over for some amount of time before the js file finally realises there is no entry in the db. Why is this?
You should first check if it exists in DB then only you should proceed with request, it should be very first statement.
If it does not exists you can send response saying code already applied.
You most likely need to lock the table ASAP so no other instances can modify the table concurrently.
http://dev.mysql.com/doc/refman/5.0/en/lock-tables.html
I did not get your problem, exactly I am assuming lost of things, so..
//this is triggered on some click, right?
//TODO:- check if button is disabled? you can have some js variable or check button attribute disbled
//TODO:-if its not disaled->{so first disable the button when it is clicked } else do nothing
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
} else { // code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
discountAmount += parseFloat(xmlhttp.responseText);
// if succefull keep button disabled
// else renable it, so that it can be clicked again.
modifyCartOrder();
}
}
xmlhttp.open("GET","forms/jsPromoCode.php?code="+code+"&type="+order_name,true);
xmlhttp.send();
thers's no syntax problem here in your code its logical,
ajax call is asynchronous call, it does not happen in sequence
1) You clicked
2) Request Sent
3) Request Processed
4) JS is informed : your modifyCartOrder function executed
what I am trying to say here is that, there is no 3 immediately after 2, 3 will take time to start, js has no control over it, whenever php is done it will reply there's no guarantee. so you can repeat 1 again and again, and 2 will keep repeating... and so 3 will...
I hope I understood your problem, and you understood what I am trying to say :)
Problem is : You are sending asynchronous ajax calls from following code :
xmlhttp.open("GET","forms/jsPromoCode.php?code="+code+"&type="+order_name,true);
Solution : as defined , for opening an ajax call , method is :
xmlhttp.open(method,url,async)
So, You have to modify above line as:
xmlhttp.open("GET","forms/jsPromoCode.php?code="+code+"&type="+order_name,false);
I'm making a quiz using AJAX to refresh each question. Instead of having individual AJAX calls for every different question in the quiz, I was wondering if there might be an easy way to use the same AJAX call but add a digit to the end of the filename each time.
So here is the basic AJAX request:
function nextQuestion()
{
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("wordbank").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","question2.php",true);
xmlhttp.send();
}
As you can see the GET request pulls a file called question2.php
xmlhttp.open("GET","question2.php",true);
This is just a stand-in file at the moment, what I really want to do is something like this:
xmlhttp.open("GET","question" i++ ".php",true);
OK, I phrased that badly, but I'm not sure if this is the best way to do this. Essentially I want to have my button bound to the nextQuestion() function, but I want to work out a way to generate the next filename based on the one you're currently on.
Is this possible?
Another idea would be to give the button on each page a different ID and have the nextQuestion() function take that ID and use it to generate the next file. E.G if you are on question 2, the button would have an ID of question2. The ajax would take the last digit (2) and add 1 to it, so the filename called would be question3.php - and that is how it would know to move to the next question.
Here you go you can now place an ID on any button and have it take you to the correct page.
Your JS
function nextQuestion(buttonID)
{
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("wordbank").innerHTML=xmlhttp.responseText;
}
}
var splitID = buttonID.split('_');
var questionID = splitID.pop();
xmlhttp.open("GET","question" + questionID + ".php",true);
xmlhttp.send();
}
Your Button
<button id="question_2" onClick="nextQuestion(this.id)">Go To Question 2</button>
or
<button id="question_14" onClick="nextQuestion(this.id)">Go To Question 14</button>
so build a string with the current index you have
xmlhttp.open("GET","question" + i + ".php",true);
You can have a global var with the current quest and do something like this:
var current_quest=1;
function nextQuestion()
{
...
xmlhttp.open("GET","question"+current_quest+".php",true);
xmlhttp.send();
window.current_quest++;
...
}
I am not familiar with ajax, I am in the process of learning, but as far as I know, it utilizes javascript to access the DOM, so my question is, is it possible to put an argument inside a function?
<script type="text/javascript">
function loadXMLDoc( * * this * * ) {
var xmlhttp;
if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
} else { // code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open("GET", ""
test.php ? access = "**+this**", false);
xmlhttp.send();
document.getElementById("myDiv").innerHTML = xmlhttp.responseText;
}
</script>
Shouldn't this work?
Thank you so much for your help.
this in JS changes according to the context you are running in. Depending on how you call it, it will change.
Read this article for more information : http://www.quirksmode.org/js/this.html
xmlhttp.open("GET",""test.php?access="**+this**",false);
This call wouldn't make much sense since this refers to an object, but what you're actually attempting to do is string concatenation (adding two strings together).
If you need to make variable calls, use a variable instead of the this keyword.
function loadXMLDoc(accessVar) {
....
xmlhttp.open("GET","test.php?access=" +accessVar ,false);
}
loadXMLDoc('accessIdentifier'); //passes the value 'accessIdentifier' to your method so it is passed along in the querystring.
You're close. It looks like you're using the example from w3schools. Be warned, that site is not always the most reliable source. See http://w3fools.com/ for more info.
Look over their code again, as it is taken from their page:
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","ajax_info.txt",true);
xmlhttp.send();
As you can see, the "on success" code is located within the onreadystatechange event handler. Your example code has three problems: one with the way you're passing a variable, two with the way you use this, and three that your response handler won't work as expected.
var xmlhttp;
var var1 = 'testdata';
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
handleAjaxResponse(responseText);
}
xmlhttp.open("GET","ajax_info.php?var1="+var1,true);
xmlhttp.send();
function handleAjaxResponse(resp) {
document.getElementById("myDiv").innerHTML=resp;
}
In terms of this, it refers to the current scope of execution, a different subject entirely. It isn't a variable you'd pass via AJAX.