AJAX/ Javascript - Pass contents of txt file into Javascript variable - javascript

I'm trying to read a list of words from a txt file into a Javascript variable to use later in my script. However, I am unable to pass the variable out of the onreadystatechange function. Is there some simple step that I'm missing?
Source:
var xmlhttp;
var list = new Array();
var word;
if (window.XMLHttpRequest) xmlhttp=new XMLHttpRequest();
else xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
list = xmlhttp.responseText.split("\n");
document.getElementById("testfield").innerHTML = list[0]; //This works
word = list[0];
}
}
xmlhttp.open("GET","wordlist.txt",true);
xmlhttp.send();
document.getElementById("testfield").innerHTML = word; //This doesn't work

The problem is that this code
document.getElementById("testfield").innerHTML = word; //This doesn't work
is being run before your xhr callback. As a result, word is undefined
This xmlhttp.send(); is sending off your ajax request, and then returning immediately. Your code then proceeds to
document.getElementById("testfield").innerHTML = word;
where word is still undefined, then, some time later, your ajax request completes, your callback is called, and word is set to the result too late for your to care.

Related

javascript worker loop ajax

I am having a worker which has an array of urls. I loop through these URLs and throw an AJAX call, but inside success method of ajax when I send message back to website, it always sends the last request.
app.js
var worker = new Worker('worker.js');
var urls = ['url1','url2','url3'];
worker.addEventListener('message', function(e) {
console.log('Worker: ', e.data.url);
}, false);
worker.postMessage({"args":[urls]});
worker.js
self.addEventListener('message', function(e) {
function load(url){
var xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
console.log(xmlhttp);
self.postMessage({'url':url});
}
}
xmlhttp.open("GET",url,true);
xmlhttp.send();
}
var urls = e.data.args[0];
for(var i = 0; i<urls.length; i++){
load(urls[i]);
}
}, false);
Now inside console.log(); of app.js, the output is only of the last url.
I don't get all all URLs response.
Can anyone help ?
The answer is real easy. make line 3
var xmlhttp=new XMLHttpRequest();
What you're doing now, is setting xmlhttp as a global variable. This means overriding the variable every time line 3 is executed.

Java Script Function not returning value from Ajax request [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 8 years ago.
I have following AJax request function which is working fine. upon successful it returns 1 else 2.
Now i would like to perform some action outside of this function based on this return value, as below, but its not working .. it always returns "undefined"...
I expect the return_code should return either 1 or 2 based on following code
<script>
var return_code=add_to_cart_ajax(200);
alert(return_code);
</script>
returns "undefined"
AJAX Request :
<script>
//Ajax to send request to add
function add_to_cart_ajax(id)
{
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); // returns 1
if (xmlhttp.responseText==1)
{
return 1;
}
else
{
return 2;
}
}
}
xmlhttp.open("GET","add.php?id="+id,true);
xmlhttp.send();
}//end of the function..
</script>
Since an AJAX call is asynchronous one common way of dealing with it is to use a callback-function that gets called once the request is processed.
Something like
<script>
add_to_cart_ajax(200, function(return_code) {
alert(return_code);
});
</script>
<script>
//Ajax to send request to add
function add_to_cart_ajax(id, callback) {
...
alert(xmlhttp.responseText); // returns 1
if (xmlhttp.responseText==1) {
callback(1);
} else {
callback(2);
}
...
}//end of the function..
</script>
EDIT: If you need to hang on to the return_code, you'd do
<script>
var return_code;
add_to_cart_ajax(200, function(result) {
return_code = result;
});
</script>
But it's important to understand that since the AJAX request is asynchronous, your return_code variable will not have a value assigned to it untill the AJAX request is fulfilled and you can't use it for anything untill that has happened, so any code that needs to do something with return_code should be included in or called from the callback. This is one of the things that is going to be a bit hard to grasp at first if you're coming from a background where all code is being run top-to-down. That's simply not the case once you start working with asynchronous stuff.
Seeing that an ajax call is async, you can't expect to have the result in your alert(return_code); because effectively at that time the ajax call has not get the response yet.
Could be useful to give a look at how libraries as jQuery or Zepto have done as well as implementing something following "promise" logic, just to avoid the callback hell.
ok i will try to make an example:
if you order a package on amazon and you want to unpack this in the next step
orderPackage();
unpackPackage(); // undefined / exception, because you have to wait for the package to be arrived
try not to return a value with the "onreadystatechange". you can call another function from inside this method or you can set global variables. as example:
Just to explain how ajax works (DO NOT USE THIS PEACE OF CODE, SCROLL DOWN FOR BETTER SOLUTION!):
ajaxReturn = null;
function add_to_cart_ajax(id) {
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)
{
ajaxReturn = xmlhttp.responseText;
}
}
xmlhttp.open("GET","add.php?id="+id,true);
xmlhttp.send();
while(ajaxReturn == null) {
//waiting for response
//will break if the request is finished
}
alert(ajaxReturn);
}//end of the function..
Please not use this in productive because the while will cause the browser to stop i think.
but this should explain the behaviour to you.
Right Solutions
// This will send an ajax-request and execute the fCallback if finished
// #param sUrl - Url to send the request to
// #param fCallbackSuccess - method that will be executed on successfull request
// #param fCallbackFailed - method that will be executed on failed request
// #param bAsync - will make the request async or sync
function ajax(sUrl, fCallbackSuccess, fCallbackFailed, bAsync) {
if (window.XMLHttpRequest) {
oXmlHttp=new XMLHttpRequest();
} else {
oXmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}
oXmlHttp.onreadystatechange=function() {
if (oXmlHttp.readyState==4 && oXmlHttp.status==200) {
fCallbackSuccess.apply(oXmlHttp);
return;
}
fCallbackFailed.apply(oXmlHttp);
}
oXmlHttp.open("GET", sUrl, bAsync);
oXmlHttp.send();
}
//usage example:
var fSuccess = function(oXmlHttp) {
//do something with oXmlHttp
alert(oXmlHttp.responseText);
}
var fFailed= function(oXmlHttp) {
//do something with oXmlHttp
alert('Request failed!');
}
ajax("add.php?id="+id, fSuccess, fFailed, true);
have a nice day

Second request receives the first one that was still processing

I have a request system where two unrelated functions are making requests to my server. But the problem is the response is not correct let me explain what is happening step by step:
A background function makes a request to the server
Server processes task 1
A second unrelated background function makes a request to the server
Client recieves response of task 1
The second function recieves that response that was for the first function.
The first function never gets a response.
Now i don't know how to solve it, but i know i need to distinguish them separately so theres no conflictions here.
This is my current code that handles the request stuff:
function call_back(result,func){
if(typeof(func) != 'undefined' || func != false){
func(result);
} else {
return false;
}
}
function caller(url,cfunc){
if (window.XMLHttpRequest)
{
xmlhttp=new XMLHttpRequest();
}
else
{
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=cfunc;
xmlhttp.open("GET",url,true);
xmlhttp.send();
}
function call_file(url,func){ //handles html files (not json_encoded)
caller(url,function(){
if ( xmlhttp.readyState== 4 && xmlhttp.status== 200 ){
call_back(xmlhttp.responseText,func);
}
});
}
function call_data(url,func,JsonBool){ //handles json_encoded data
caller(url,function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200){
call_back(JSON.parse(xmlhttp.responseText),func);
}
});
}
What can i do to my functions, for preventing this behaviour?
Here is an example of how you could structure your code - I have used this, it works, but it could be refined.
function Ajax(url, callback,args){
var xhttp = init();
xhttp.onreadystatechange = process;
function init() {
if(window.XMLHttpRequest)
return new XMLHttpRequest();
else if (window.ActiveXObject)
return new ActiveXObject("Microsoft.XMLHTTP");
}
function process() {
if (xhttp.readyState==4 && xhttp.status==200) {
if (callback) callback(xhttp.responseText,args);
else return xhttp.responseText;
}
}
this.Get=function(){
xhttp.open("GET", url, true);
xhttp.send(null);
}
}
To use it:
var url = '/someurl';
var ajax = new Ajax(url,yourCallback,parameters);
ajax.Get();
I believe DRobinson was talking about something like this but more robust. This should be a good example to get you started though.
It looks to me as though you're using a global/window variable for xmlhttp. If this is the case, certain parts of the second call will overwrite the first. Consider using an Object Oriented approach, or otherwise instantiating these as vars in different scopes.

How to do a request to the server and liberate JavaScript to continue processing

Is there a way to make a request and liberate JavaScript and HTML to do their own thing, leaving the Server to do its thing until it completes, at which point an event grabs control of JavaScript, dumps the data to a designated receiving end and ends the call?
I use this method for calling Python
function par_makeHttpObject() {
try {
return new XMLHttpRequest();
}
catch (error) {}
try {
return new ActiveXObject("Msxml2.XMLHTTP");
}
catch (error) {}
try {
return new ActiveXObject("Microsoft.XMLHTTP");
}
catch (error) {}
throw new Error("Could not create HTTP request object.");
}
And I call it as follows:
...
var request = par_makeHttpObject();
request.open("POST", "../getFdList?Fds=allFds", false);
request.send();
var dta = request.responseText.split("\n");
var cnt = 0;
for (var x in dta) {
try {eval(dta[x]);}
catch (error) {alert("JS Error - check JS part of syntax!\n" + dta[x]);}
}
...
The problem is that JavaScript sits and waits for a reply to the request and the user could be doing something else. Some calls take 5 minutes...
Any ideas would be appreciated.
DK
Use jQuery's ajax() function instead of rolling your own AJAX solution. ajax() defaults to asynchronous requests, so you can pass it a function that is called on request completion:
$.ajax({
type: "POST",
url: "../getFdList?Fds=allFds"
}).done(function( msg ) {
alert( "Response: " + msg );
});
That way, you can call ajax(), give it your callback function, and carry on with whatever other processing you need to do.
Another plus for jQuery is that it's pretty well cross-browser without any effort.
Yes, it's very easy in fact. Change the last parameter in your open call to "true":
(I pulled this from w3schools(Yes I'm aware of the sites bad rep, this is just an example))
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)
{
//THIS IS WHERE YOU GET THE SERVER RESPONSE
var response = xmlhttp.responseText;
}
}
xmlhttp.open("GET","ajax_info.txt",true);
xmlhttp.send();
}
The best part about AJAX is the ability to continue working on something else while the HTTP request is being made asynchronously.
$.post('../getFdList?Fds=allFds', {}, function(response) {
var dta = response.split("\n");
// ...
}, 'text');
// continue doing something else here
See also: $.post()

JS Function not returning return

I have the follwing function:
function anfahrtskosten()
{
var xmlhttp;
var entfernung=0;
var anfahrtskostenergebnis=0;
var anfahrtskostenergebnis1=0;
var plz=document.modhochzeitskalk.plz.value;
//aus den Parametern
var anfahrtskosten=1;
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)
entfernung = xmlhttp.responseText;
if (entfernung > 100 && entfernung < 2000) {
anfahrtskostenergebnis1 = anfahrtskosten * entfernung;
} else {
anfahrtskostenergebnis1 = 0;
}
anfahrtskostenergebnis = Math.round(anfahrtskostenergebnis1);
document.getElementById("anfahrtskostenergebnis").innerHTML=anfahrtskostenergebnis+",00 €";
}
xmlhttp.open("GET","/modules/mod_hochzeitskalk/ogdb_remote.php?plzstart=10245&plzend="+plz,true);
xmlhttp.send();
return anfahrtskostenergebnis;
}
I want to use the number stored in the var anfahrtskostenergebnis within another function, I tried it like this:
var gesamtkosten = anfahrtskosten() + videokosten() + filmkosten() + fotokosten() + extrakosten();
But it doesnt work, what am I doing wrong?
Because you are using AJAX, you can not continue processing until the AJAX call returns. The call is Asynchronous, meaning, the program flow continues, and the AJAX call is run in a paralel thread.
It makes a lot of sense to do it this way, as the alternative is to halt all script activity whist you wait for slow network traffic to deliver a result.
You need to re-structure your program to use callback functions, which are called after the value has been returned via AJAX.
This should get you started, but I suspect you are going to have to do similar things for the other functions you add together, and keep track somehow of the values that have already been collected, running the final callback once they are all retrieved.
function anfahrtskosten(){
var xmlhttp;
... your original code here...
anfahrtskostenergebnis = Math.round(anfahrtskostenergebnis1);
// call the callback here, with the value you retrieved
callback(anfahrtskostenergebnis); // <~~~~
document.getElementById("anfahrtskostenergebnis").innerHTML=anfahrtskostenergebnis+",00 €";
}
xmlhttp.open("GET","/modules/mod_hochzeitskalk/ogdb_remote.php?plzstart=10245&plzend="+plz,true);
xmlhttp.send();
}
var callback = function(anfahrtskosten){
var gesamtkosten = anfahrtskosten + videokosten() + filmkosten() + fotokosten() + extrakosten();
// do something with cost...
}
You are missing a start brace '{' after if (xmlhttp.readyState==4 ... (ie., your if is only executing the first statement)
a really easy solution or goaround is to store the varibale somewhere in the document in a innerhtml, what I did already in my example
document.getElementById("anfahrtskostenergebnis").innerHTML=anfahrtskostenergebnis+",00 €";
so the second functions can reuse this value by reading it from the innerHTML.
In my case I needed also to set a small timeout before executing the second function, to be sure

Categories

Resources