Dom manipulations are not synchronized with javascript code on ajax request? - javascript

In my below code, I tried to stimulate how each statement gets executed line by line while processing synchronous ajax requests. I have sent two ajax requests synchronously introducing a delay between two requests. The problem is i'm getting "Request 1" in console but not getting the response text in my dom. After delay ends, and my second request ends, the first responseText is displayed and then second responseText is displayed in my dom.
Why My first ajax response text getting late to update in my dom, even though I got a response from server-side before the delay gets start?
index.html
-----------
<!DOCTYPE html>
<html>
<body>
<!--Calls the function synchronously(async=0/false) -->
<button type="button" onclick="loadDoc('ajax_info.txt')">Synchronous Operations</button>
<p id="result1"></p>
<p id="result2"></p>
</body>
<script type="text/javascript">
function loadDoc(url) {
console.log("Entered ");
ajax(1,url,"result1");
for(i=0;i<1000000000;i++){}
ajax(2,url,"result2");
console.log("Exit");
}
function ajax(requestNo, url, div) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById(div).innerHTML = this.responseText;
console.log("Request " + requestNo);
}
};
xhttp.open("get", url, 0);
xhttp.send();
}
</script>
</html>
ajax_info.txt
--------------
This is the content from a txt file.

I think there is something wrong with your response. I used a publicly available fake endpoint to reproduce this, but it works as expected:
https://jsbin.com/kojowaneda/1/edit?html,js,console,output
The only diff between this code and yours, is the parameter of the function call:
<button type="button" onclick="loadDoc('https://jsonplaceholder.typicode.com/todos/1')">Synchronous Operations</button>
Also, you should use setTimeout for a timeout instead of a for loop.

Related

Understand call back function in this code

I see this code in other website but I do not
understand the specific cFunction and url
function loadDoc(url, cFunction) {
var xhttp;
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
cFunction(this);
}
};
xhttp.open("GET", url, true);
xhttp.send();
}
function myFunction(xhttp) {
document.getElementById("demo").innerHTML =
xhttp.responseText;
}
<div id="demo">
<h2>The XMLHttpRequest Object</h2>
<button type="button" onclick="loadDoc('ajax_info.txt', myFunction)">Change Content</button>
</div>
In the code you posted there is a function loadDoc that takes as sercond argument another function, the callback cFunction.
loadDoc, as the name says, loads a document from the internet, identified by the url argument, using ajax. When the document is loaded the cFunction function, passed as argument, is called passing the reference of the current XMLHttpRequest.
All the stuff loadDoc do, are done when the user clicks on the button, the document that have to be loaded is ajax_info.txt and the callback function is myFunction
So myFunction is called by loadDoc when the document is downloaded with the XMLHttpRequest object that contains the response, as argument, so myFunction can read the response and print it on an HTML element.
In modern browsers you can use JavaScript debugging tools like console.log and the debugger statement

Javascript loaded by an Ajax call doesn't execute?

I´m trying to implement html code with Ajax-get into my temp-page.
This works as it should, only the javascript isn´t executed as I expected. If I load the code independently in the browser, then the javascript executes as expected. If it's implemented with Ajax in my temp-page it doesn´t. Why?
Here is the html and javascript code I'm loading:
<link rel="stylesheet" type="text/css" href="/x/x/x/x/stylesheet.css">
<div id='content_Box'></div>
<script type="text/javascript" src="/x/x/x/x/javascript.js" charset="utf-8"></script>
And here is the ajax code which loads it:
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
content_Box.innerHTML = "";
content_Box.innerHTML = this.responseText;
}
};
xhttp.open("GET", Pfad, true);
xhttp.send();
Thank you for your time!
Your problem is not with the ajax call.
The issue is that
content_Box.innerHTML = this.responseText;
doesn't cause any scripts to execute.
See Executing <script> elements inserted with .innerHTML for some code that looks at the text, finds the scripts, and executes them.
It may depend on what your js actually does.
Anyway you can call the functions once you have loaded the ajax response (in xhttp.onreadystatechange) to make sure to run them at least once also on the parts you got from the response.

Changing a element text based on xhttp.readyState on javascript/jquery

I have a button that user clicks and download from a PHP page, since the processing is a little bit long i want to display a text that shows the user that their request is processing, i found the onreadystatechange Property can be accessed so maybe I can use it for the task.
ready StateHolds the status of the XMLHttpRequest.
0: request not initialized
1: server connection established
2: request received
3: processing request
4: request finished and response is ready
My code is below, i able the get the readyState == 4 but cannot get the readyState == 3, any advice would be great!
<button type="submit" class="btn btn-primary" id="weekDL">
<i class="fa fa-download"></i>
Download
</button>
<p id="please">Generating report, please wait..</p>
$('#weekDL').on('click',function(){
$(this).hide();
$('#please').show();
var data = $("#week option:selected").text();
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if(this.readyState == 3) {
$('#please').text('Request recieved..');
} else if (this.readyState == 4 && this.status == 200) {
window.location = "PHPexcel/download.php?week=" + data;
this.responseText;
$('#please').hide();
$('#weekDL').show();
}
};
xhttp.open("GET", "PHPexcel/download.php?week=" + data, true);
xhttp.send();
});
});
Your code is working fine. The issue is because state 3 is only around for a couple of milliseconds before state 4 occurs (depending on the size of the response), therefore your UI update is almost imperceptible.
You can verify this by placing console.log('state: ' + this.readyState); within the onchangereadystate handler. You will then see the output of all 4 states in the console.
Working example
This is of course assuming that the AJAX request is returning a valid response. If there is an error in the request then you would only see states 1 and 4. However in that case the problem is with the logic in the request, not your JS.

if (xmlhttp.readyState==4 && xmlhttp.status==200) in AJAX not executing

I was trying ajax on my page. But it is not working as if (xmlhttp.readyState==4 && xmlhttp.status==200) is always false. I have alerted the values of xmlhttp.readyState and xmlhttp.status. There values are always 1 and 0 respectively for xmlhttp.open event and 4 & 0 respectively for xmlhttp.close event.
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript">
function captcha_check()
{
var code = document.getElementById("captcha").value;
var url = "http://www.opencaptcha.com/validate.php?img='.$captcha_name.'.jpgx&ans="+code;
var xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange=function() {
alert(xmlhttp.readyState + " " + xmlhttp.status);
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
document.getElementById("captcha_error").innerHTML=xmlhttp.responseText;
return false;
}
}
xmlhttp.open("GET","captcha_check.php?img=abc.jpg&ans="+code,true);
xmlhttp.send();
}
</script>
What the issue may be and how can I solve it and make the AJAX functioning. Thanks in advance.
The correct order of calls is:
new XMLHttpRequest
xhr.open()
xhr.onreadystatechange = ...
xhr.send()
In some browsers, calling .open clears any event handlers on it. This allows for clean re-use of the same XHR object, which is supposedly more memory-efficient (but that really doesn't matter if you code properly to let the GC do its job)
So, simply put the .open call before the onreadystatechange assignment and you should be good to go.
Even though your code is working perfectly, as mentioned in the comments, since your already included jQuery try:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript">
function captcha_check() {
var code = document.getElementById("captcha").value;
var url = "http://www.opencaptcha.com/validate.php?img='.$captcha_name.'.jpgx&ans="+code;
jQuery.get("captcha_check.php?img=abc.jpg&ans="+code", function(data) {
alert("Load was performed.");
console.log(data);
});
}
</script>
It almost sounds like you are making an AJAX request from a page loaded in the browser directly from the file system, rather than from a Web Server. Since you are issuing a GET request, browser caching might be an issue as well. Try appending a timestamp to the URL each time so the URL is unique:
xmlhttp.open("GET", "captcha_check.php?img=abc.jpg&ans=" + code
+ "&__cachebuster__=" + new Date().getTime());
Secondly, you need to escape the code variable to make it safe for a query string:
xmlhttp.open("GET", "captcha_check.php?img=abc.jpg&ans=" + escape(code)
+ "&__cachebuster__=" + new Date().getTime());
Lastly, please check for any occurences of $_POST in your captcha_check.php file, as this would indicate you should be issuing a POST request, not a GET request.
If:
You are loading a page in the browser directly from the file system, AJAX requests will fail
You enter non query string safe characters for the code, then you end up with an invalid URL, and AJAX requests will fail
The captcha_check.php file requires a POST request and you issue a GET request, the AJAX request will fail.
xmlhttp.open("GET","captcha_check.php?img=abc.jpg&ans="+code,true);
Please check file path, maybe its wrong path.

Adobe AIR and multiple XMLHttpRequests is being... weird

I'm making a small Adobe AIR app (my first) using HTML+Javascript. I need to run more than one asynchronous data request, but the second one didn't seem to be firing (note that the requests were not run concurrently originally). I tried stripping the program down to the bare minimum that exhibited problems, and at first only the first request fired, but then things got strange. Code and output follows:
<html>
<head>
<script type="text/javascript" src="AIRAliases.js"></script>
<script type="text/javascript">
function download(page) {
var url = "http://en.wikipedia.org/w/api.php?action=parse&format=xml&page=" + page;
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", url,true);
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState == 4) {
air.trace("Done");
}
}
xmlhttp.send(null);
}
function appLoad() {
download("Main Page");
download("Main Page");
}
</script>
</head>
<body onLoad="appLoad()">
</body>
</html>
Expected output:
Done
Done
Actual output:
C:\AIRSDK\apps\HelloWorld>adl HelloWorld-app.xml
Done
C:\AIRSDK\apps\HelloWorld>adl HelloWorld-app.xml
Done
C:\AIRSDK\apps\HelloWorld>adl HelloWorld-app.xml
Done
C:\AIRSDK\apps\HelloWorld>adl HelloWorld-app.xml
Done
Done
Done
Done
Done
Done
Done
Anyone seen anything like this before?
Simple answer, you shouldn't re-use xmlhttprequest objects (even if you don't realise you are because you're a complete noob at Javascript).
This line:
xmlhttp = new XMLHttpRequest();
Should be:
var xmlhttp = new XMLHttpRequest();

Categories