AJAX, client-side JavaScript processed before server-side JavaScript? - javascript

I have a question as to how client-side code is processed along with server-side responses.
I have some code (too complex and long to post here) that when it runs, calls a function which runs some server-side code using a HTTPRequest Object, and returns a string to the page that the function was called from. For some reason, I think that the client-side code is being processed, the string is returned (too late) and my code is failing because of it. For example, I call my function with the HTTPRequest, next line I try to display the returned value (the string from the HTTPRequest) in an alert, and the alert shows up as blank. A few lines later in the code though, the same alert shows up with the value returned. So, basically, I am under the impression that the first client-side alert is being processed so that it displays a string which has not yet been returned, whereas the second alert was processed later, (ergo. giving the server time to process the request) and displaying the requested string. Does this theory sound logical? Will client-side code run, regardless of whether or not a HTTPRequest was completed? If so, are there any ways to prevent the client-side code from executing until a response is received from the server?

An HTTP Request is asynchronous. That means your code is going to send it and continue on with it's execution. You need to set up a callback function that takes the data returned by the XHR request, and uses that data in some way.

You need to bind an anonymous function to the onreadystatechange event of the XmlHttpRequest object so:
//xhr is an instance of the XmlHTTPRequest object that you have opened correctly
xhr.onreadystatechange = function(){ //4 means the request was successful
if (xhr.readyState === 4){
//Your code here
}
}

You need to make sure that your bit of code that attempts to display / act on the returned value is within the scope of the ajax routine. That's the only way to guarantee that the response will not be acted upon until the request has been completed (whether successfully or not). For example, if you are using jQuery:
CORRECT
jQuery.get('ajax/ajax.getSomeData.php',{id:id}, function(data) {
$('#myDIV').html(data);
});
INCORRECT
jQuery.get('ajax/ajax.getSomeData.php',{id:id}, function(data) {});
$('#myDIV').html(data);

Related

jQuery Ajax: Sucess Response parameter overwriting

I am having a strange problem where the response param of 1st ajax call is being overwritten by the 2nd call's param.
Code is:
http://pastebin.com/degWRs3V
When both drawDonutForExternalLogin & drawDonutForExtUser are called consecutively,the response variable of the later request(data param of success handler) overwrites the data param of 1st request.
The calls do complete almost at the same time always but when there is a difference this problem doesn't occur.The data set is also fine when the 2nd function is invoked from the success handler of 1st function.
Why the data param becomes identical when the calls are consecutive and finish at the same time?
I tried debugging the server side code by placing breakpoints but that also provides the delay between ajax requests thereby yielding correct result.
Any ideas please?
Copied from stackoverflow.com/questions/5583478/java-servlets-ajax-requests-come-back-with-mixed-responses to OP's request :
The likely cause is that the servlets are not written to be thread
safe. Note that the object that contains the servlet methods may be
used to respond to many simultaneous requests. If that method uses a
class level variable to create the response, then requests will appear
to get 'mixed up'.
So.. Request #1 comes in, is assigned to an instance of Servlet,
Instance #1
The appropriate method is invoked on Instance #1, which starts using a
class variable to calculate the result. Instance #1.myVariable =
"Blah"
Now, Request #2 comes in, is also assigned to Instance #1
Again, the appropriate method is invoked on Instance #1, which sets
Instance #1.myVariable ="Foo"
.. in the mean time the first request completes, and returns Instance
1.myVariable... "Foo"!
.. and then the second request completes, and also returns "Foo".

Understanding asynch behaivor of javascript with an example

I'm completely new in javascript and I'm trying to understand its asynch nature. For this purpose here is my sample code :
$("#calculate-similarity").click(function(){
// assume input is an array whose length is larger than 0
var requestData={"uris":input,"limit":100};
client=new Ajax(requestData);
alert('inside .click function');
})
Ajax=function(requestData){
alert('inside ajax');
$.ajax({
url: 'http://localhost:8080/',
type:'POST',
dataType: 'json',
contentType: 'application/json',
data: JSON.stringify(requestData),
xhrFields: {
withCredentials: true
}
}).done(function(data) {
$("#ws-results").children().detach();
$("#ws-results").append('<table id="my-final-table"><thead><th>fname</th><th>furi</th><th>sname</th><th>suri</th><th>similarity</th></thead><tbody></tbody></table>');
$('#my-final-table').dynatable({
dataset: {
records:data
}
});
});
}
Now, above, I'm creating new Ajax() and inside of it, I'm making a ajax request. As far as I know its asynch event. Therefore, I though that, this request should be completed first of all, and then my other javascript lines (alert('inside .click function')) should be executed. In other words, I would expect :
1) alert inside ajax
2) show my datatable on the browser
3) alert inside .click function
However, I got with the following order :
1) alert inside ajax
2) alert inside .click function
3) show table on the browser
So, what do you suggest me to understand these concepts ? I've a solid background with several programming languages like c++ and java but this is my first time with web development and javascript.
EDIT
If I modify my .click function like below, do you say first of all always 10000 times hello will be printed out and then table will be shown ? Or table would be shown somewhere at the middle of logging ? I mean when the response comes, engine should wait first in order to show it ?
Modified code : (Let's remove all of the alert statements)
$("#calculate-similarity").click(function(){
// assume input is an array whose length is larger than 0
var requestData={"uris":input,"limit":100};
client=new Ajax(requestData);
for(var z=0;z<10000;z++){
console.log(z+'hi!');
}
})
As far as I know its asynch event. Therefore, I though that, this request should be completed first of all, and then my other javascript lines should be executed.
That is exactly the opposite of what it means.
The Ajax function will run. It will trigger an HTTP request. The Ajax function will finish. alert will run.
At some point in the future, the HTTP response will arrive and the done event handler will fire.
This is exactly the same principle as:
alert(1);
$("#calculate-similarity").click(function(){ alert(2); });
alert(3);
JavaScript doesn't wait for you to click on calculate-similarity before firing alert(3).
If I modify my .click function like below, do you say first of all always 10000 times hello will be printed out and then table will be shown ? Or table would be shown somewhere at the middle of logging ? I mean when the response comes, engine should wait first in order to show it ?
JavaScript won't interrupt a running function in order to execute a different (event handler) function. It will wait until it isn't busy before it goes looking for events.
new Ajax is object instantiation and it's synchronous. Therefore you get inside ajax as the first result because it happens when your Ajax object is instantiated, not to be confused with when the Ajax request is fired.
alert is executed synchronously, so that's the second thing you get.
$.ajax which wraps around XMLHttpRequest, responsible for firing the actual ajax request, is the only async part in your code and its result, which is encapsulated inside done, is what you get last.
In other words, I think the confusion comes from the fact that you introduce another layer of abstraction called new Ajax() which provide little actual value and a lot of confusion :P. inside ajax signal inside the instantiation of your Ajax object, not the firing of the actual request.
I'll try my best to explain it. Think of this more as an analogy, it's not exactly what's going on but I think it might help you understand:
alert('inside ajax'); - this is a blocking call, it will run and wait for you to click OK.
Then when you call Ajax, what you're essentially doing is saying "go make this web request when you have a chance, and when it finishes call my done method." That's a network operation. It could finish in 1 second, it could take many seconds. Rather than freezing up the whole browser, this is done "in the background." So that makes the UI remains responsive. At some point in the future the network request will finish. When it does, the function you specified in done will get called to let you know it finished. Think of making the Ajax request as adding it to a queue rather than actually connecting to the network. When the browser gets to it it will execute your request and wait for the server to respond. When it does, it will signal you to let you know.
Next you alert('inside .click function'); which displays the alert and blocks.
Like I said, that's not a technically accurate description of what's going on, but I'm hoping it helps you understand the principle of it.

Procedural order of jQuery functions inside JS [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What does Asynchronous means in Ajax?
jQuery ajax return value
Trying to do a function that contains a jQuery function (getJson()) as part of it, but when I run it, my javascript function returns before calling the getJson(). I want to know why the getJson is not being called in order, and how to fix it.
function getUsers(screen_name){
user_list=[]
var id_list =[]
$.getJSON(url, function(json)
{
//do stuff here, I have breakpoint #1 here
});
return user_list //breakpoint #2 is here
}
When running it from the console: getUsers('myUser') it firsts gets to breakpoint #2 and then to breakpoint #1.
getJSON() is asynchronous by default. That means that calling it just starts the operation and the rest of your javascript continues to run. Sometime later, the asynchronous operation finishes and the success handler is called with the returned data.
Any code that needs access to the returned data must either be in the success handler or in a function that you call from the success handler. You cannot use an asynchronous function and just return the user_list like you are trying to.
Instead, you will have to rethink how your code is organized so that the code that uses the user_list is in the success handler or is called from the success handler.
getJSON() can be set to be synchronous, but that is generally a bad way to program in javascript because it locks up the browser for the duration of the networking call which is generally a bad user experience. Instead, if you write the code properly to deal with it being aschronous, then the browsers stays completely interactive for the full duration of the ajax call.

javascript outside of scope

Based on chrome developer tools a breakpoints I think I'm dealing with a scope issue I can figure out. Is it the way I define the function? The script below is an include js file and the array ' timeStamp I want available for use in other functions without having to call my loadData function everytime.
The timeStamp array goes undefined once it leaves the for loop before it even leaves the function.
var timeStamp = []; // Want this array to be global
function loadData (url){
$.getJSON(url, function(json) {
for (var i=0;i<json.length;i++){
timeStamp.push(json[i].TimeStamp);
}
console.log(inputBITS); //returns the value
});
console.log(inputBITS); //undefined
}
Thank you for anyhelp
It looks like the issue is that getJSON is asynchronous. When it executes and finishes and your code continues on, it indicates only the START of the networking operation to retrieve the data. The actual networking operation does not complete until some time later.
When it does complete, the success handler is called (as specified as the second argument to your getJSON() call) and you populate the timeStamp array. ONLY after that success handler has been called is the timeStamp array valid.
As such, you cannot use the timeStamp array in code that immediately follows the getJSON() call (it hasn't been filled in yet). If other code needs the timeStamp array, you should call that code from the success handler or use some other timing mechanism to make sure that the code that uses the timeStamp array doesn't try to use it until AFTER the success handler has been called and the timeStamp array has been populated.
It is possible to make some Ajax calls be synchronous instead of asynchronous, but that is generally a very bad idea because it locks up the browser during the entire networking operation which is very unfriendly to the viewer. It is much better to fix the coding logic to work with asynchronous networking.
A typical design pattern for an ajax call like this is as follows:
function loadData (url){
$.getJSON(url, function(json) {
// this will execute AFTER the ajax networking finishes
var timeStamp = [];
for (var i=0;i<json.length;i++) {
timeStamp.push(json[i].TimeStamp);
}
console.log(timeStamp);
// now call other functions that need timeStamp data
myOtherFunc(timeStamp);
});
// this will execute when the ajax networking has just been started
//
// timeStamp data is NOT valid here because
// the ajax call has not yet completed
// You can only use the ajax data inside the success handler function
// or in any functions that you call from there
}
And here's another person who doesn't understand basic AJAX...
getJSON is asynchronous. Meaning, code keeps running after the function call and before the successful return of the JSON request.
You can "fix" this by forcing the request to be synchronous with an appropriate flag, but that's a really bad idea for many reasons (the least of which is that you're violating the basic idea of AJAX). The best way is to remember how AJAX works and instead put all your code that should be executed when the AJAX returns, in the right place.

How do I write a JS function to do something and then return once that process is done?

I'm adding some functionality to an existing function. I need to insert an additional step in the middle of the current routine. I know how to go to the 2nd function but I don't know what to do to return to the main function once the 2nd routine completes.
function step1(){
perform ajax call to see if student is assigned to a project
step1_subfunction()
// wait here until step1_subfunction is done
do some more stuff with response from user
}
function step1_subfunction(){
prompt user via jQuery dialog, 'Add or move employee to the project?'
// return to step1 with answer returned from user and resume
}
I'd google this but I don't know if this "process" has a name. Back in my days of COBOL, we called this gosub.
UPDATED:
Step1 performs an ajax call to see if an employee has been assigned to a project. If the response.status = 'Assigned', the user will be asked via a jQuery dialog box, "Do you want to copy or move the employee to this project?". The jQuery dialog box will be step1_subroutine. The answer will be passed back to the step1 function. The remaining part of step1 will simply be to place a value in a hidden text field of "copy" or "move".
What you have will perform what you are describing, but may not make the data from the user available to function step1() without a return in function step1_subfunction(). Below I've modified your example code to demonstrate the passing of values back.
function step1(){
//do some stuff
var returnValFromFunction = step1_subfunction();
// wait here until step1_subfunction is done
// Now use returnValFromFunction, it contains the information from the user
do some more stuff with response from user
}
function step1_subfunction(){
prompt user for some information
// return to step1 with information returned from user and resume
return userResponse;
}
What you've written should work - javascript is single-threaded, so have you tried it?
Javascript doesn't have subroutines specifically, just create a function that returns and ignore the result, as you have done. When the second routine completes, the scope and execution will continue in the first function.
just do nothing.
what you are trying to achieve is just a "function call"
so it will automatically return to it's caller "stack frame" once executed.
You can make the ajax object synchronous - IE, no code will continue until it gets a response. It's the third parameter of open (true is asynchronous, false is synchronous).
xmlhttpobject.open('POST', 'url', false);
There are cases where a synchronous call is fine but it should always be avoided if possible.
The other alternative, which would likely require some logic changes in your code but would be better off in the long run, is to bind the onReadyStateChange event. This fires every time the state of the xmlHttpRequest object changes - you can check to see if the status is 200 and the readystate is 4 to make sure the request is done and completed successfully.
Here's a better reference. Good luck.

Categories