Complete ajax call before body loads - javascript

I read in w3schools that there are several ways an external script can be executed:
If async is present: The script is executed asynchronously with the rest of the page (the script will be executed while the page continues the parsing)
If async is not present and defer is present: The script is executed when the page has finished parsing
If neither async or defer is present: The script is fetched and executed immediately, before the browser continues parsing the page.
So, if i understood correctly, since i have the following script in the head section of my html file
without using async or defer it should first be executed and then the browser will continue parsing.
<script type="text/javascript" src="js/display.js"></script>
display.js
$.ajax({
url:"fetch_items.php"
});
fetch_items.php fetches some items from the database and puts them in an array $_SESSION("my_array").
So inside the body section of the html folder i use the values that reside in $_SESSION("my_array") to show some content.
<?php
if(isset($_SESSION["my_array"]))
{
?>
<!-- html code echoing values from session -->
<?php
}
?>
but $_SESSION["my_array"] isn't set yet so the content doesn't appear. (if i reload the page the content will appear correctly)
Why is this happening? How can i ensure that the script has completed it's execution before the body loads? is the following refers only to scripts :
If neither async or defer is present: The script is fetched and executed immediately, before the browser continues parsing the page.

AJAX stands for "Asynchronous JavaScript and XML". So it makes asynchronous request from your browser by running your javascript code. Your current code makes request from browser to server. Then server saves your array to session by using your PHP code and not reloads the page. That is why your array not printing immediately.
Bad solution: Refreshing page on success method of your ajax request.
Better solution: Don't keep your array in session if it is not really necessary. Return your array in the method at "fetch_items.php". Then print the array using success callback of the ajax request.
Here is an example for usage of success and print method: Ajax response inside a div
For more information you can read jquery api documentation: http://api.jquery.com/jquery.ajax/

Try putting async : false in your ajax call parameters.

This is because of asynchronous calls. I encountered similar issue and fixed it by adding async:false in AJAX. You may see the below code fragment I used.
$.ajax({
type: "GET",
url: "fetch_items.php",
data: {},
async : false, // make it false
success: function (html) {
alert (html);
}, error: function (error) {
alert (error);
}
});

Related

Ajax $.post with document.ready in success

Hi I am running an AJAX Post to my PHP url and when done I am returning a document.ready function with my appended jQuery page.
I want to make sure if I am doing this correctly when placing the function in the success part of my AJAX post. It will not work at the minute. Any help would be great?
function loadJobRequests() {
/ /AJAX code to submit form.
$.ajax({
type: "POST",
url: "http://localhost:8888/EduSubOct/json-data-
jobrequests.php",
data: { userEmail: localStorage.getItem("email") },
cache: false,
success: function() {
$(document).ready(function(){
        
I just need to find out if i have to pass any parameters into the function at success and then same same parameter into document.ready. Thanks
Short answer: no, you shouldn't use $(document).ready(...) here. The function you put inside that is only executed at the moment the DOM is first "readied", shortly after page load - this will be long since past by the time your script has been loaded, executed, fired an Ajax call and then returned the response (all of which needs to happen before your success callback happens).
But the very reason that $(document).ready(...) doesn't work also means that you don't need it here. The only reason it's used is to make sure that any DOM elements you refer to (typically to attach event handlers to) actually exist and the point this code is executed. Since the "ready" event has long since fired by the time the Ajax response comes in, the DOM will accurately reflect the current content of the page, and you can safely do whatever you want to manipulate it.
So whatever function you were going to put inside there, just put directly in the success callback.

Ajax Call Confusion

before we start apologies for the wording and lack of understanding - I am completely new to this.
I am hoping to run a php script using Ajax - I don't need to send any data to the php script, I simply need it to run on button press, after the script is run I need to refresh the body of the page. What I have so far:
HMTL Button with on click:
<font color = "white">Next Question</font>
JS Ajax call:
function AjaxCall() {
$.ajax({
url:'increment.php',
type: 'php',
success:function(content,code)
{
alert(code);
$('body').html(content);
}
});
}
this runs the php script but doesn't stay on the current page or refresh the body - has anyone got any ideas - apologies if this is completely wrong I'm learning - slowly.
Many thanks in advance.
**As a small edit - I don't want a user to navigate away from the page during the process
How about using load instead of the typical ajax function?
function AjaxCall() {
$(body).load('increment.php');
}
Additionally, if you were to use the ajax function, php is not a valid type. The type option specifies whether you are using GET or POST to post the request.
As far as the dataType option (which is what I think you mean), The Ajax doesn't care what technology the called process is using (like ASP or PHP), it only care about the format of the returned data, so appropriate types are html, json, etc...
Read More: http://api.jquery.com/jquery.ajax/
Furthermore, if you are replacing the entire body content, why don't you just refresh the page?
your ajax should be
function AjaxCall() {
$.ajax({
url:'increment.php',
type: 'post',
success:function(data)
{
console.log(data);
$('body').html(data);
}
});
}
if you want to learn ajax then you should refer this link
and if you just want to load that page then you can use .load() method as "Dutchie432" described.
If you are going to fire a javascript event in this way there are two ways to go about it and keep it from actually trying to follow the link:
<font color = "white">Next Question</font>
Note the return false;. This stops the following of the link. The other method would be:
<font color = "white">Next Question</font>
Note how this actually modifies the href to be a javascript call.
You can study about js and ajax here http://www.w3schools.com/ajax/default.asp will help a lot. Of course all js functions if called from internal js script should be inside <script></script> and if called from external you call the js gile like <script src"somejs.js"></script> and inside js there is no need for <script> tags again. Now all those function do not work by simply declaring them. So this:
function sayHello(){
alert("Happy coding");
}
doesn't work because it is just declared and not called into action. So in jQuery that you use after we declare some functions as the sayHello above we use:
jQuery(document).ready(function($){
sayHello();
});
Doing this we say that when everything is fully loaded so our DOM has its final shape then let the games begin, make some DOM manipulations etc
Above also you don't specify the type of your call meaning POST or GET. Those verbs are the alpha and omega of http requests. Typically we use GET to bring data like in your case here and POST to send some data for storage to the server. A very common GET request is this:
$.ajax({
type : 'GET',
url : someURL,
data : mydata, //optional if you want to send sth to the server like a user's id and get only that specific user's info
success : function(data) {
console.log("Ajax rocks");
},
error: function(){
console.log("Ajax failed");
}
});
Try this;
<script type="text/javascript">
function AjaxCall() {
window.location.reload();
}
</script>
<body>
<font color = "white">Next Question</font>
</body>

Unable to load MathJax dynamically

I have a ajax post request, which dynamically loads some math content like below
// post comment
$post_comment.on("click", "[data-submit='post-comment']", function() {
$.ajax({
success: function(response) {
if(response.success) {
$('#comment-list').load(' ' + '#comment-list');
MathJax.Hub.Queue(["Typeset",MathJax.Hub, "comment-list"]);
}
},
});
});
The mathjax command above mentioned is unable to render the math script loaded dynamically.
While when I execute the same command on command-line, its working!!
It would be nice if someone explains why this is happening and how to fix
The load() method uses ajax which executes asynchronously meaning after the request is sent to the server the statements after that will continue executing without waiting for the response from server comes back.
In this case when the load request is sent, before #comment-list is populated with the response the MathJax.Hub.Queue(["Typeset",MathJax.Hub, "comment-list"]); statement will get executed, thus it is not rendering anything.
The solution is to use a callback provided by load to run the statements which has to work on elements loaded by the ajax request
Ex
$('#comment-list').load(' ' + '#comment-list', function(){
MathJax.Hub.Queue(["Typeset",MathJax.Hub, "comment-list"]);
});

Requesting something via ajax - how to stop other requests until this one is done

I have a php script that outputs json data. For the purposes of testing, i've put sleep(2) at the start.
I have a html page that requests that data when you click a button, and does $('.dataarea').append(data.html)
(php script returns a json encoded array. data.html has the html that i want to put at the end of <div class="dataarea">...HERE</div>.
The trouble is, if i click the button too fast (ie. more than once within two seconds (due to the sleep(2) in the php script)), it requests the php file again.
how can i make it only do one request at a time?
i've tried this (edited down to show the important parts):
amibusy=false;
$('#next').click('get_next');
function get_next() {
if (amibusy) {
alert('requesting already');
}
else {
amibusy=true;
// do the request, then do the append()
amibusy=false;
}
}
but this doesn't seem to work. i've even tried replacing the amibusy=true|false, with set_busy(), and set_not_busy(). (and made a function am_i_busy() { return amibusy; })
but none of this seems to work. what am i missing?
If you're in jQuery the amibusy would be jQuery.active which contains a count of currently active AJAX requests, like this:
if(jQuery.active > 0) { //or $.active
alert('Request in Progress');
}
Keep in mind that in jQuery 1.4.3 this becomes jQuery.ajax.active.
Disable the button in the click event and enable it again when the request is finished. Note that the request is asynchronous (i.e. "send request" returns immediately), so you must register a function that is called when the answer comes in.
In jQuery, see the load() function and the success method plus the various AJAX events which you can tap into with ajax().
I'm wondering about your "do request" logic. Whenever I've done calls like this they've always been asynchronous meaning I fire the request off and then when the response comes another function handles that. In this case it would finish going through that function after setting the callback handler and set your value of amibusy back to false again before the request actually comes back. You'd need to set that variable in the handler for your post callback.
Could you use the async variable?
http://api.jquery.com/jQuery.ajax/
asyncBoolean Default: true
By default, all requests are sent
asynchronous (i.e. this is set to true
by default). If you need synchronous
requests, set this option to false.
Cross-domain requests and dataType:
"jsonp" requests do not support
synchronous operation. Note that
synchronous requests may temporarily
lock the browser, disabling any
actions while the request is active.

Problem accessing the content of a div when that content came from an Ajax call

Here's a very simple Prototype example.
All it does is, on window load, an ajax call which sticks some html into a div.
<html>
<head>
<script type="text/javascript" src="scriptaculous/lib/prototype.js"></script>
<script type="text/javascript">
Event.observe(window, 'load', function(){
new Ajax.Request('get-table.php', {
method: 'get',
onSuccess: function(response){
$('content').innerHTML = response.responseText;
//At this call, the div has HTML in it
click1();
},
onFailure: function(){
alert('Fail!');
}
});
//At this call, the div is empty
click1();
});
function click1(){if($('content').innerHTML){alert('Found content');}else{alert('Empty div');}}
</script>
</head>
<body><div id="content"></div></body>
</html>
The thing that's confusing is the context in which Prototype understands that the div actually has stuff in it.
If you look at the onSuccess part of the ajax call, you'll see that at that point $('content').innerHTML has stuff in it.
However when I check $('content').innerHTML right after the ajax call, it appears to be empty.
This has to be some fundamental misunderstanding on my part. Anyone care to explain it to me?
Edit
I just want to clarify something. I realize that the Ajax call is asynchronous.
Here's the actual order that things are being executed and why it's confusing to me:
The page loads.
The Ajax request to get-table.php is made.
The call to click1() INSIDE onSuccess happens. I see an alert that the div has content.
The call to click1() AFTER the Ajax call happens. I see an alert that the div is empty.
So it's like the code is executing in the order it's written but the DOM is not updating in the same order.
Edit 2
So the short answer is that putting the code in onSuccess is the correct place.
Another case to consider is the one where you do an Ajax call and then do another Ajax call from the onSuccess of the first call like this:
new Ajax.Request('foo.php',{
method: 'get',
onSuccess: function(response){
doAnotherAjaxCall();
}
});
function doAnotherAjaxCall(){
new Ajax.Request('foo.php',{
method: 'get',
onSuccess: function(response){
//Anything that needs to happen AFTER the call to doAnotherAjaxCall() above
//needs to happen here!
}
});
}
The first letter of AJAX stands for "asynchronous". This means that the AJAX call is performed in the background, i.e. the AJAX request call immediately returns. This means that the code immediately after it is normally actually executed before the onSuccess handler gets called (and before the AJAX request has even finished).
Taking into account your edited question: in some browsers (e.g. Firefox), alert boxes are not as modal as you might think. Asynchronous code may pop up an alert box even if another one is already open. In that case, the newer alert box (the one from the asynchronous code) gets displayed on top of the older one. This creates the illusion that the asynchronous code got executed first.
Without having tried your code: The AJAX call is executed asynchronously. Meaning that your Ajax.Request fires, then goes on to the click1() call that tells you the div is empty. At some point after that the Ajax request is finished and content is actually put into the div. At this point the onSuccess function is executed and you get the content you expected.
It's Ajax call, which is asynchronous. That means right after that request call, response hasn't come back yet, that's why $('content') is still empty.
The onSuccess element of the function call you are making to handle the AJAX call is executed at the time you receive a response from get-table.php. This is a separate Javascript function which you are telling the browser to call when you get an answer from get-table.php. The code below your AJAX.Request call is accessed as soon as the AJAX.Request call is made, but not necessarily before get-table.php is called. So yes I think there is a bit of a fundamental misunderstanding of how AJAX works, likely due to using a library to hide the details.

Categories

Resources