1

I have a function that calls another function and I want to store the returned result in a variable:

function trigger_gridly(){
    var channel_name = get_channel_name();
}

The called function triggers an AJAX request, which triggers a callback receiving JSON:

function get_channel_name(){
    var channel_name;     
    $.getJSON(APPLICATION_DOMAIN + "channels/new.json?callback=?", null, handleJson);
}

function handleJson(channel){
    var channel_name = channel.name;
    return channel_name;
}

The problem is that the channel_name in trigger_gridly() does not receive the value of channel_name in the handleJson callback function. How can I expose the data in the callback to the trigger_gridly() function?

Justin Meltzer
  • 13,318
  • 32
  • 117
  • 182
  • You are thinking about this in a synchronous fashion. Doing an asynchronous request and having a simple getter function that returns the value is not possible unless the value has been prepopulated. What exactly are you trying to do? It will likely need to be more callback oriented than your trigger_gridly function. – Corbin Jan 14 '12 at 08:55
  • I'm trying to get a json object on the client side from a different domain than the server is on. – Justin Meltzer Jan 14 '12 at 08:58
  • And do what with it? Perhaps you should pass your function that actually does the processing as the callback. Otherwise, how are you going to know when the variable has been set and when it hasn't been? (Without using something hacky like an infinite loop that breaks once it's set or something.) – Corbin Jan 14 '12 at 09:06
  • 1
    possible duplicate of [JavaScript asynchronous return value / assignment with jQuery](http://stackoverflow.com/questions/7779697/javascript-asynchronous-return-value-assignment-with-jquery) – Felix Kling Jan 14 '12 at 10:10

3 Answers3

1

As others have indicated, getJSON is an asynchronous call. You have to wait for it to invoke your callback before channel will be available. Here is how I might code it up:

function trigger_gridly() {
   get_channel_name(function(channel){
      var channel_name = channel.name;
      // Do something with channel_name
   });
}

function get_channel_name(success) {
   $.getJSON(APPLICATION_DOMAIN + "channels/new.json?callback=?", null, success); 
}

EDIT: An alternative that I like slightly better:

function trigger_gridly(channel) {
   var channel_name = channel.name;
   // Do something with channel_name
}

function get_channel_name(success) {
   $.getJSON(APPLICATION_DOMAIN + "channels/new.json?callback=?", null, success);
}

get_channel_name(trigger_gridly);
erturne
  • 1,799
  • 1
  • 15
  • 29
0

it's quite ugly, but this will work, asynchronous processes are always a bit tricky getJSON is async.

function get_channel_name(fn) {
    $.getJSON(APPLICATION_DOMAIN + "channels/new.json?callback=?", null, function(channel) {
        fn(channel.name);
    });
}

var channel_name;
get_channel_name(function(name) {
    channel_name = name;
});
// but here channel_name is still undefined
greut
  • 4,305
  • 1
  • 30
  • 49
  • This will work since eventually `channel_name` will be defined. But it won't be defined where you might expect it to be. Meaning right after calling `get_channel_name`. – greut Jan 14 '12 at 10:17
  • That's what I meant, but I have to apologize, I misread the comment in your code, I thought it was saying it was *defined* from the point on. Guess it's still too early for me ;) Never mind, I deleted my comment.... – Felix Kling Jan 14 '12 at 10:19
0

You need to declare channel_name outside the function scope. However, I am not sure this will get you what you want. This is set up for an async request/response. You want to perform your actions that use the channel name in the handleJson() function.

Like this:

var CHANNEL_NAME;

function trigger_gridly(){
    get_channel_name();
}

function get_channel_name(){
    $.getJSON(APPLICATION_DOMAIN + "channels/new.json?callback=?", null, handleJson);
}

function handleJson(channel){
    CHANNEL_NAME = channel.name;
}
saarp
  • 1,931
  • 1
  • 15
  • 28