Forum Moderators: open

Message Too Old, No Replies

JavaScript function not returning string!

         

JAB Creations

10:01 pm on Sep 10, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I can alert the string just fine inside the function. However it's absolutely refusing to return the string. If I alert a function with a returned value it works as desired...

alert(hi_mom());
function hi_mom()
{
var a = 'available';
return a;
}

This does not work however. I can alert but not return the string. I've tried assigning it to a variable and returning and a few other things. Why is it refusing to work?

- John

function example() {
//more code here

if (xmlHttp.readyState==4 ¦¦ xmlHttp.readyState=='complete')
{
//alert(xmlHttp.responseText); works, return does not?!
return xmlHttp.responseText;
}
}

poppyrich

12:06 am on Sep 11, 2008 (gmt 0)

10+ Year Member



Looks fine. Which browser giving trouble?

JAB Creations

12:39 am on Sep 11, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



No...the problem is that it's not returning xmlHttp.responseText!

The whole point is to make the AJAX function reusable regardless of the request.

Essentially I have an ajax.php file that detects certain $_GET queries. The PHP works fine and the JavaScript works up to the return.

I can alert xmlHttp.responseText but not return it! That means I can't make the AJAX script reusable!

The rest of the script doesn't matter as it works. If you look at the commented out alert if I uncommon it in my script it will correctly alert the text generated by the ajax.php file.

So I have a small JavaScript function that calls this reusable AJAX function. I'll eventually add more functions that use this reusable AJAX function. However if it can't return anything then it's worthless! I'd have to copy and paste the whole function all over again just because I can't return the value!

By returning a string you get the string by an alert outside of the function.

function hi_mom()
{
var a = 'available';
return a;
}

alert(hi_mom()); //will alert 'available'

In the function I'm using to call the AJAX checker function that isn't returning it keeps alerting undefined. Therefor I know the AJAX function isn't returning the AJAX result even though it can alert it!

I could really cheap out and change an element's innerHTML but that's cheap. This problem has burned half my day already.

- John

httpwebwitch

2:02 am on Sep 11, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



AJAX calls within a function do not "return" as you'd expect them to... that's a synchronous action, whereas AJAX things happen asynchronously.

To make a reuseable AJAX function, you actually need two functions. One makes the request, and the other responds to the onreadystatechange event of the scoped XHR object.

I would highly highly recommend you grab one of the wickedly good libraries available for doing this. My favourite is Mootools; but JQuery, Dojo and prototype are also very popular. You can accomplish in one line of code what will otherwise take days of anguish and debugging.

you are essentially trying to reinvent the Mootools Request Object [docs.mootools.net]

Fotiman

2:58 am on Sep 11, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Or the Yahoo UI Library [developer.yahoo.com]'s Connection Manager. :)

JAB Creations

12:22 pm on Sep 11, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



NO LIBRARIES! It's been making me angry that all the threads I've encountered online while searching where someone received their answer for anything remotely close to this problem ended up using a library. Why would I post on a JavaScript forum to learn how to write JavaScript to only end up piling on an extra twenty seconds of load time for 15% of internet users because I couldn't figure out how to write it myself? That's a rhetorical question of course. I could cheap out and pass a parameter of an id where I could change the text but that's still completely unacceptable. My only option is to write the script correctly.

The problem with two functions is this: If I have my first function called the AJAX reusable function...then I have to call the third function...but I still have to return the value taken from the server!

I know this is what you're mentioning...
xmlHttp.onreadystatechange=stateChanged;

...in the script below, though I'm not sure how to then reference xmlHttp.onreadystatechange as a variable (which I presume it's not) and even if I could the function can't return any thing any way!

I don't expect AJAX itself to return the text string (which in most circumstances is less then 10 characters total). I've tried assigning it to a variable and some goofy stuff as I blew half of yesterday dealing with this issue. I need a fresh idea please.

- John

function check_ajax(field)
{
var user_data = document.getElementById(field).value;
xmlHttp=check_ajax_GetXmlHttpObject()
if (xmlHttp==null) {alert ('Browser does not support HTTP Request'); return;}
var url='_1_functions_ajax.php';
url=url+'?'+field+'='+user_data;
url=url+'&sid='+Math.random();
xmlHttp.onreadystatechange=stateChanged;
xmlHttp.open('GET',url,true);
xmlHttp.send(null);
}

function stateChanged()
{
if (xmlHttp.readyState==4 ¦¦ xmlHttp.readyState=='complete')
{
return xmlHttp.responseText;
//alert(xmlHttp.responseText);
//if (xmlHttp.responseText == 'unavailable') {var a = 'unavailable'; return a;}
//else if (xmlHttp.responseText == 'available') {var a = 'available'; return a;}
}
}

function check_ajax_GetXmlHttpObject()
{
var xmlHttp=null;
try
{
// Firefox, Opera 8.0+, Safari
xmlHttp=new XMLHttpRequest();
}
catch (e)
{
//Internet Explorer
try {xmlHttp=new ActiveXObject('Msxml2.XMLHTTP');}
catch (e) {xmlHttp=new ActiveXObject('Microsoft.XMLHTTP');}
}
return xmlHttp;
}

Fotiman

2:18 pm on Sep 11, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month




NO LIBRARIES! It's been making me angry that all the threads I've encountered online while searching where someone received their answer for anything remotely close to this problem ended up using a library.

There is a good reason for that. Most of the libraries handle cross browser issues for you, they are well proven to work, and are probably more efficient than what many developers might create on their own.


Why would I post on a JavaScript forum to learn how to write JavaScript to only end up piling on an extra twenty seconds of load time for 15% of internet users because I couldn't figure out how to write it myself?

For one thing, it prevents you from having to re-invent the wheel. Sure, you could do it yourself, and there's certainly nothing wrong with that either. There's a decent AJAX tutorial [w3schools.com] at w3schools.

It's worth noting, though, that many of the libraries have been optimized for performance. For example, the Yahoo UI Library [developer.yahoo.com] offers minified versions of all it's files (something that most developers don't take the time to do themselves). In addition, if you use the files hosted by Yahoo, they are GZIPped, and could in theory already be in your visitors cache if they visited another site using that library. My point is that saying it adds 20 seconds of load time for 15% of users is a great over-exaggeration.

I'm not trying to deter you from learning to do it yourself. I just wanted to point out that the libraries are not evil.

:-)

Fotiman

2:31 pm on Sep 11, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



As httpwebwitch pointed out:

AJAX calls within a function do not "return" as you'd expect them to... that's a synchronous action, whereas AJAX things happen asynchronously.

Asynchronously means that you fire an event and it goes off and does it's own thing, calling a callback method. In other words:

alert('1'); // Synchronous - Doesn't continue until complete 
alert('2'); // Another synchronous call
check_ajax('foo');
// That method is syncrhonous, but inside it is an
// asychronous call xmlHttp.send(null). When that call
// is reached, it will send the request to the server
// and then continue on with whatever is next.
alert('3'); // This might be reached before or after
// your AJAX request calls your callback method stateChanged

I don't know if I explained that well.

[edited by: Fotiman at 2:32 pm (utc) on Sep. 11, 2008]

JAB Creations

8:53 pm on Sep 11, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I don't think I've made it clear: The AJAX part works. It successfully receives the data from the server.

It's passing the data from the AJAX function as a return that is not working.

I can statically execute what I want directly during xmlHttp.readyState==4 ¦¦ xmlHttp.readyState=='complete' but that would mean I'd have to create the whole AJAX function all over again per operation I want to use it for or at least pass tons of unnecessary parameters.

Thanks for trying to help with libraries but libraries be dammed. The less I have to depend on others and entire frameworks just to do something that should be simple the better.

I've had a suggestion to start using something that looks like this...

Ajax.request = function(method, uri, callback) {

...how can I reference that as a function? I have no clue... I know that I declare a function as function my_func_name() {//...}.

It seems there are a ton of AJAX scripts out there but none of them seem to be written with reusability in mind. I'm feeling numb at this point going through so much useless code not intended for scalability. :(

- John

Fotiman

12:00 pm on Sep 12, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



You've made it perfectly clear. I understand that your AJAX part works. I don't know how to state it any more clearly: A call to an asynchronous method does not "return" a value because your callback method is not called inline with the regular flow of your other script.

Where do you think you are returning a value to?

DrDoc

5:45 pm on Sep 12, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



To explain it differently. Imagine a floor manager in a factory. He has a task list that looks as follows:
Push button A
Push button B
Ask Joe to push a button
Push button C

There is no guarantee that Joe has pushed his button before button C is pushed. If pushing of button C is dependant on Joe pushing his button, then the process will fail.

That is what is happening to you.

Fotiman

6:32 pm on Sep 12, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Nice analogy! :-)

JAB Creations

7:22 pm on Sep 12, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Why does assigning the AJAX text from the server to a variable and then returning the variable fail then?

- John

JAB Creations

1:08 am on Sep 13, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Got it working.

AJAX wasn't work so I changed it to SJAX instead. ;)

- John

Fotiman

3:47 pm on Sep 15, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Why does assigning the AJAX text from the server to a variable and then returning the variable fail then?

Because you're not returning the value to the original function that called your AJAX request. Your XMLHttpRequest/Msxml2.XMLHTTP/Microsoft.XMLHTTP object calls the onreadystatechange method when it gets a response back from the server... it's not as if the method that called the AJAX send is going to get the reply because (as stated over and over already) this is an Asynchronous call (AJAX = Asynchronous JavaScript and XML).

It seems you've found a solution by using a Synchronous call instead. Make sure you read up on the pitfalls of such an approach (the browser will stop processing all requests until it gets a reply, so you're at the mercy of the network... this can give the appearance of a crashed browser).