views:

234

answers:

2

I'm trying to return a value from (transport) to the calling function, but can't seem to get it to work:

function createXMLHttpRequest( w )
{
  var urly = '/users/notes/' + w;
  var options = {
      method:'get'
    , onSuccess: function( transport )
      {
        x = transport.responseText;
        return x;
      }
    , onFailure: function( transport )
      {
        var response = transport.responseText;
        alert( "FAILED "+ response );
      }
  };
  new Ajax.Request( urly, options );
  alert( x );
}

var ai = $( 'addItem' );
ai.onclick = function()
{
  // -1 indicates new
  addnote( -1, null );
}

x always alerts undefined. Unless I assign x to the Ajax.Request e.g. x=new Ajax.Request(urly,options). It then will alert [Object object]. How can I return the value of transport.responseText to the onclick function?

+1  A: 

Your Request is not asynchronous:false. So x is alerted before the request is completed and x is set to transport.responseText.

You have to either set the request as synchronous, or alert x in the onSuccess method.

The return value from onSuccess is discarded by Ajax.Request. Don't return anything.

Ajax is asynchronous by nature. You should query the server, then handle the response in a callback. So you should not try to use the server value in the onclick function, but rather in a separate callback (the onSuccess method).

Alsciende
Saweet. Thanks. The docs say the following: "Since synchronous usage is rather unsettling, and usually bad taste, you should avoid changing this. Seriously." Why is it unsettling, and in bad taste? Is it just because it's not then truly ajax?
stormdrain
It's not just hype. Making the request synchronous will slow your UI down, and you'll risk having your js thread blocked by some net failure.
Alsciende
OK. Thanks for the help!
stormdrain
A: 

This is just wrong!

When doing ajax calls you should forget to think synchronous, think asynchronous instead! Send the request to some url and send a callback function that will be executed once request returns some data.

I wrote simple wrapper for GET calls

// AJAX WRAPPER
MYPROJECT = {};
MYPROJECT.Ajax = (function() {
    return{

        // get data by AJAX call and return as plain text
        get:function(url, callback) {
            new Ajax.Request(url, {
                method: 'get',
                onSuccess: function(transport) {
                    var data = transport.responseText.evalJSON();
                    callback(data);
                }
            });
        }
    }    
})();

// USAGE  
MYPROJECT.Ajax.get('/ajax_json_echo/?foo=bar',function(data){

    alert(data);
    $('containerText').innerHTML = data.get_response.foo
}); 

You can see the code in action here http://jsfiddle.net/wbDhY/1/

(please be patient, the alert box should appear in 2 seconds)

kodisha