0

What I want is for data retrieved from one function to be displayed in another . I was told that using a global variable would allow me to accomplish this What is the best way to store a value for use in a later function? I'm hearing global variables are evil.

Here is what I tried. http://jsfiddle.net/8j947/17/

When I try to display the global variable as an alert it comes back as undefined (which might not be viewable on jsfiddle). I'm thinking this is because the data isn't actually getting stored, but I've only been coding for 3 weeks, so what do I know. If you guys could help me out by showing me what I did wrong or proposing an alternate solution that would be great.

Community
  • 1
  • 1
davis
  • 1,911
  • 6
  • 26
  • 50
  • There's nothing wrong with global variables. Just don't make everything global. Remember, the A in AJAX is "asynchronous", which means you make your request and the result comes back sometime later. So if you check for the result right away, chances are, it won't be there yet. The "callback" is a function that picks up the response when it comes. That's the key. – Diodeus - James MacFarlane Aug 12 '11 at 00:19
  • @Diodeus Sure there is (something wrong with global variables) - they should be avoided. Ideally, you want to use only one global variable which represents your application / web-site / company / ... - like `YAHOO`, or `StackOverflow` - and then use it as your namespace... – Šime Vidas Aug 12 '11 at 00:42
  • @Davis Note that the variable in your jsFiddle demo is not a global variable since you're declaring it inside the page load handler. – Šime Vidas Aug 12 '11 at 00:50

2 Answers2

0

Your alert function at the bottom is executing immediately after getCrossDomainJson is called, and before the callback function passed into getCrossDomainJson is called. Since the someProperty property is set inside the callback function, when you refer to it in the alert, it hasn't actually been set yet.

Give your alert function a name and call it somewhere else AFTER the callback function completes.

function getCrossDomainJson(url, callback) {
    $.ajax({
        url: "http://query.yahooapis.com/v1/public/yql?callback=?",
        data: {
            q: 'select * from xml where url="' + url + '"',
            format: "json"
        },
        dataType: "jsonp",
        success: callback
    });
}

var MyStatus = {};
getCrossDomainJson("http://xdiscgolfplanetx.channel-api.livestream-api.com/2.0/getstream", function(data) {
    // data is in JSON format:
    console.dir(data);
    if (data && data.query && data.query.results && data.query.results.channel) {
        var isLive = (data.query.results.channel.isLive);
        MyStatus.someProperty = data.query.results.channel.isLive;
    // alert (isLive)
        if (isLive == 'true') {
            alert ('working')
        }
        alertSomeProperty();            // now that the someProperty property has been set and MyStatus 
                                        //is global, you'll see that you can refer to it even outside of this block
    }
});

function alertSomeProperty(){
    alert (MyStatus.someProperty)
}
achow
  • 1,013
  • 2
  • 12
  • 20
  • How would I go about doing that? Thanks for the answer – davis Aug 12 '11 at 00:47
  • @Davis Well, call the alert from within the Ajax-callback function... that's why it's for in the first place. Or put the alert inside some other function and then call that other function from within the callback. – Šime Vidas Aug 12 '11 at 00:49
  • @Sime So I called it from the callback (I think) and it is still undefined. http://jsfiddle.net/8E6vH/ – davis Aug 12 '11 at 01:29
  • @Davis In your demo, you're never calling the `callback` function (the one that you pass in into `getCrossDomainJson`). You have to put the alert inside that function. Like so: http://jsfiddle.net/simevidas/8E6vH/1/ – Šime Vidas Aug 12 '11 at 01:42
  • I've edited my post with one possible way of alerting the `MyStatus.someProperty`. I've chosen to call it at a place absolutely after the property has been set. But it also demonstrates that the property is defined outside the block, since the function is defined outside the block. It demonstrates that indeed global names are as global as you think they are :p (disclaimer: untested code) – achow Aug 13 '11 at 04:19
0

This is a classic mistake when using asynchronous programming. You can no longer think of a single stepwise order of execution, call function a(), then b(), then c(). When using any form of ajax call, it is usually asynchronous. That means that calling the function only starts it's execution.

It will then run in the background and the rest of your javascript will keep running and finish. Then, sometime later, the ajax call will complete and it will call it's success function. ONLY from that success function or any other code that you call from the success function can you actually use the results of your ajax call. So, what you essentially have to do is start the ajax call and then your javascript code finishes for the moment. You then write a success function which will pick up execution of the rest of what you need to do when the ajax call completes. At that point, you have your JSON data and you can do with it what you want. You can take that data and call other functions, passing it along to them so they can operate on it.

So, kick of your second step of execution from the success handler. Whatever you need to do with the retrieved data should start in the success handler.

So, if the flow of execution you wanted to do was this:

a();
b();
getJSONdata();
c();
d();

You would have to structure it like this:

a();
b();
getJSONdata("xxx", function(data) {
    c(data);
    d();
})

function c(myData) {
    // do something with the passed in data
}

where c() and d() are happening in the success function from retrieving the JSON data and they are called ONLY after the data is available.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • I want to have a function use the data after the request has finished, how can I prevent it from being undefined? – davis Aug 12 '11 at 00:54
  • See my second example above. You call a function that uses the data from the success handler and you pass the data to that function as a parameter. In my example, that is this line `c(data);` of code. The way you have your code structured, you would do this inside the function you have declared inside of `getCrossDomainJson` as that is the completion handler. – jfriend00 Aug 12 '11 at 00:57