ajax synchronous call problem - javascript

I have an Ajax function which looks like :
function getData(p) {
loadingImage();
p = p.replace("frame_", "");
if (window.XMLHttpRequest) {
AJAX=new XMLHttpRequest();
} else {
AJAX=new ActiveXObject("Microsoft.XMLHTTP");
}
if (AJAX) {
var __page =encodeURIComponent(p);
AJAX.open("GET", "page.php?page="+__page, false);
AJAX.send(null);
var __data = AJAX.responseText.match(/<data>[\s\S]*?<\/data>/gmi);
if(!__data) { return false; }
return __data;
} else {
return false;
}
}
then i have very simple loading function ( an loading image must appear in center of page ) :
function loadingImage(type)
{
document.getElementById("body").innerHTML = "<div class='loading'></div>";
}
then how i call ajax function :
var loadedData = getData("home");
if(loadedData)
{
document.getElementById("body").innerHTML = loadedData;
}
else
{
document.getElementById("body").innerHTML = "Error";
}
but the loading image won't appear, it's quite simple, but i'm stuck here , how make it to show that loading image while requesting data, then to replace loading image with loaded data. Thanks

function getData(p, cb) {
loadingImage();
p = p.replace("frame_", "");
if (window.XMLHttpRequest) {
AJAX = new XMLHttpRequest();
} else {
AJAX = new ActiveXObject("Microsoft.XMLHTTP");
}
if (AJAX) {
var __page = encodeURIComponent(p);
AJAX.open("GET", "page.php?page=" + __page, true);
AJAX.onreadystatechange = function(e) {
if (AJAX.readystate === 4) {
var __data = AJAX.responseText.match(/<data>[\s\S]*?<\/data>/gmi);
cb(data);
}
};
AJAX.send(null);
} else {
cb(null);
}
}
getData("home", function(loadedData) {
if (loadedData) {
document.getElementById("body").innerHTML = loadedData;
}
else {
document.getElementById("body").innerHTML = "Error";
}
});
Use async = true in the .open call.
Bind an eventhandler to readystatechange. If the readystate is 4 (LOADED) then get the data and send it to your callback.
If the AJAX fails call the callback with null or false.
In your callback get the loadedData and either render it or throw an error if there is no data.

Related

Return datas inside XMLHttpRequest.onreadystatechange [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 7 years ago.
I have this function :
function getDatas() {
var xmlhttp = new XMLHttpRequest();
var response = null;
xmlhttp.open("POST", "getdatas.php", true);
xmlhttp.onreadystatechange = function() {
if(xmlhttp.readyState === 4) {
if(xmlhttp.status === 200) {
response = xmlhttp.responseText;
return response;
}
else {return xmlhttp.statusText;}
}
};
xmlhttp.send(null);
}
The response is in a JSON format and correctly filled.
How to return the response for another use like :
var datas = getDatas();
UPDATE :
After the callback I have this :
function AppViewModel() {
var _self = this;
getDatas(function(error, result) {
if(error) {
alert(error);
} else {
_self.datas = result;
console.log(_self.datas);
}
});
console.log(_self.datas);
}
The first console.log(_self.datas); works well but the second is undefined.
AJAX is asynchronous, so you don't return any values from such functions, you use callbacks and use the value inside the callback:
function getDatas(callback) {
var xmlhttp = new XMLHttpRequest();
var response = null;
xmlhttp.open("POST", "getdatas.php", true);
xmlhttp.onreadystatechange = function() {
if(xmlhttp.readyState === 4) {
if(xmlhttp.status === 200) {
response = xmlhttp.responseText;
callback(null, response);
}
else {
callback(xmlhttp.statusText, null);
}
}
};
xmlhttp.send(null);
}
and then when you call the getDatas function you provide a callback which will be invoked when the AJAX request finishes and it will either contain the result or an error:
getDatas(function(error, result) {
if (error) {
alert('An error occurred while retrieving data: ' + error);
} else {
// Use the result variable here
}
});

Second call out of two xmlhttprequest doesn't work

I've read a lot of how to try and make two xmlhttprequest in parallel, but it looks like something doesn't quite work.
I have 1 php file. which includes 2 .js files.
The first runs xmlhttprequest every 3 seconds.
I want the second to run on demand, but whenever i trigger it, it returns with status 4 but the responseText is always empty. (the PHP file prints with no question, i even tried to put on the PHP file just window.open('1') to see that the file is called and its not).
Here is the first JS :
var req1 = createXMLHttpRequest2();
var user_redirected = false;
function createXMLHttpRequest2() {
var ua2;
if(window.XMLHttpRequest) {
try {
ua2 = new XMLHttpRequest();
} catch(e) {
ua2 = false;
}
} else if(window.ActiveXObject) {
try {
ua2 = new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
ua2 = false;
}
}
return ua2;
}
function set_user_redirected_false() {
user_redirected = false;
}
function get_user_redirected() {
return user_redirected;
}
function handleResponse(username, game_id, isInvitation) {
if(req1.readyState == 4 && req1.status==200) {
var response = req1.responseText;
if (response == "true") {
// Ask to set the game_accepted var to 1 (user is redirected and not leaving)
user_redirected = true;
if (isInvitation == "true") {
window.location.href = "game.php?game_id="+game_id+"&position=2";
} else {
window.location.href = "game.php?game_id="+game_id+"&position=1";
}
}
else {
setTimeout(function(){sendRequest();}, 3000);
}
}
}
function sendRequest() {
user_redirected = false;
var username = "";
var game_id = -1;
var isInvitation = "false";
username = document.getElementById("username").value;
game_id = document.getElementById("game_id").value;
isInvitation = document.getElementById("invitation").value;
if (isInvitation == "true") {
req1.open('GET', 'check_for_inviter.php?username='+username+'&game_id='+game_id ,true);
} else {
req1.open('GET', 'check_for_opponent.php?username='+username+'&game_id='+game_id,true);
}
req1.onreadystatechange = function(){handleResponse(username, game_id, isInvitation);};
req1.send(null);
}
This is the second JS file :
function createXMLHttpRequest() {
var ua;
if(window.XMLHttpRequest) {
try {
ua = new XMLHttpRequest();
} catch(e) {
ua = false;
}
} else if(window.ActiveXObject) {
try {
ua = new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
ua = false;
}
}
return ua;
}
function delete_waiting_games(username) {
var req2 = createXMLHttpRequest();
req2.open('GET', 'delete_waiting_games_for_username.php');
req2.onreadystatechange = function(){
window.open(req2.readyState+'&'+req2.responseText);
};
req2.send(null);
}
As you can see i open a new window to see the response and the ready state (just for testing) and i always get status 4 and empty responseText.
Thanks.
Use setTimeout to separate the calls, and with to encapsulate the XMLHTTPRequest:
function xhr()
{
with(new XMLHttpRequest)
{
open("GET",{},true);
setRequestHeader("Foo", "Bar");
send("");
onreadystatechange = handler;
}
}
function handler(event)
{
!!event.target && !!event.target.readyState && event.target.readyState === 4 && ( console.log(event) );
}
setTimeout(xhr, 500);
setTimeout(xhr, 1000);

AJAX request in IE (all versions)

http://kiwilocals.com.au/dev/
Hello, here is the ajax requests on a category in the middle of the page under the banner. Work everywhere, in addition to all versions of IE.
I checked the developer's tools, a query gives the correct structure, but nothing on the loading icon does not appear after loading. In what may be the reason? Thank you.
function scat(th) {
wait_loading('sub_lst');
if (request = create_request()) {
request.open("GET", "get_subcat.php?id=" + th + "&site=1", true);
request.onreadystatechange = function () {
//alert(request);
if (this.status == 200) {
if (this.readyState == 4) {
var doc3 = document.getElementById('sub_lst');
//alert(doc3);
doc3.innerHTML = this.responseText;
if (!scroll_start) {
$('.sub_scroll').jScrollPane({
animateScroll: true
});
$('.hidden_control').show();
scroll_start = true;
}
}
}
}
request.send(null);
}
}
function create_request() {
var request = false;
try {
request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e2) {
try {
request = new XMLHttpRequest();
} catch (e3) {
request = false;
}
}
}
if (!request) {
alert("Невозможно выполнить Ajax запрос.");
return false;
} else return request;
}
function wait_loading(el_id) {
document.getElementById(el_id).innerHTML = "<center><img style=\"padding-top: 60px;\" width=\"64\" height=\"64\" src=\"images/loading.gif\"></center>";
}
The problem is with your use of 'this' in the readstatechange event.
Give this a shot.
if(request = create_request()) {
request.open("GET", "get_subcat.php?id="+th+"&site=1", true);
request.onreadystatechange = function() {
if(request.status == 200) {
if( request.readyState == 4 ) {
var doc3 = document.getElementById('sub_lst');
doc3.innerHTML=request.responseText;
if(!scroll_start) {
$('.sub_scroll').jScrollPane({animateScroll: true});
$('.hidden_control').show();
scroll_start=true;
}
}
}
}
request.send(null);
}
But one question... you use jQuery throughout your code, except for this. Why not use:
$('#sub_lst').load("get_subcat.php?id="+th+"&site=1", function(){
if(!scroll_start) {
$('.sub_scroll').jScrollPane({animateScroll: true});
$('.hidden_control').show();
scroll_start=true;
}
});

How can I change this variable with ajax?

I'm curious as to why this isn't working, here's the code:
function Ajax(sUrl, fCallback) {
var url = sUrl || '';
var callback = fCallback || function () {};
var xmlhttp = (function () {
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
} else if (window.ActiveXObject) {
try {
return new ActiveXObject("Msxml2.XMLHTTP.6.0");
} catch (e) {
try {
return new ActiveXObject("Msxml2.XMLHTTP.3.0");
} catch (err) {
return new ActiveXObject("Microsoft.XMLHTTP");
}
}
} else {
return null;
}
}());
this.setUrl = function (newUrl) {
url = newUrl;
};
this.setCallback = function (func) {
callback = func;
};
this.request = function (method, data) {
if (xmlhttp === null) { return false; }
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState === 4) {
callback(xmlhttp.status, xmlhttp.responseXML, xmlhttp.responseText);
}
};
data = data || '';
data = encodeURIComponent(data);
if ((/post/i).test(method)) {
xmlhttp.open('POST', url);
xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xmlhttp.send(data);
} else {
var uri = data === '' ? url : url + '?' + data;
xmlhttp.open('GET', uri);
xmlhttp.send();
}
return true;
};
return this;
}
var ajax = new Ajax(''); // sets the url, not necessary for this demonstration
var changed = false;
function change() {
changed = true;
}
function foo() {
ajax.setCallback(change);
ajax.request();
alert(changed);
}
foo();
There is a fiddle here: http://jsfiddle.net/dTqKG/
I feel like the change function would create a closure that would indeed change the changed variable. Does anyone know what's going on?
The ajax.request(); will return before change() is called. That is the async nature of the AJAX calls, and the reason why you need the callback as opposed to just getting return value from send() method.
Other than that there might be some other issues in the code. I question why wouldn't you use one of the many AJAX frameworks readily available instead of writing your own.

XMLHttpRequest.open is not a function

I've been trying to get my code off the ground, but I've run into a constantly occurring error across all browsers that tells me my ajax object does not include an open function. I'm sure something I've typed is wrong, but forgive me, as JavaScript is not my strong suit :)
window.onload = function(){init();}
function init() {
ajax = ajaxInit();
ajax.onreadystatechange = update(ajax);
ajaxContact(ajax);
setInterval("ajaxContact('"+ajax+"')",5000);
}
function ajaxInit() {
if (window.XMLHttpRequest) {
ajax = new XMLHttpRequest();
}
else {
if (window.ActiveXObject) {
ajax = new ActiveXObject("Microsoft.XMLHTTP");
}
}
if (ajax) {
document.getElementById("status").innerHTML = "AJAX initialized";
return ajax;
}
else {
docuement.getElementById("status").innerHTML = "Error: AJAX not available";
return false;
}
}
function ajaxContact(ajax) {
try {
ajax.open("GET","updateAjax.php?" + "ran=" + Math.random(),true);
ajax.send();
}
catch (err) {
alert(err.message);
document.getElementById("status").innerHTML = "Error contacting server";
document.getElementById("loading").src = "images/redx.png";
}
}
function update(ajax) {
if (ajax.readyState==4 && ajax.status==200){
dataObj = jsonTranslate(ajax);
document.getElementById("status").innerHTML = dataObj.status;
document.getElementById("frame").innerHTML =
"Frame:" + dataObj.firstFrame + "/" + dataObj.lastFrame;
document.getElementById("thumbnail").src = dataObj.imgSrc;
}
if (ajax.status==404) {
document.getElementById("status").innerHTML = "Ajax updater not found";
document.getElementById("loading").src = "images/redx.png";
}
}
function jsonTranslate(ajax) {
return eval('(' + ajax.responseText + ')');
}
You are passing the ajax variable as a string...
setInterval("ajaxContact('"+ajax+"')",5000);
Try replacing that with...
setInterval(function() { ajaxContact(ajax); }, 5000);

Categories