1

I thought this is how you make a variable inside a if/else block global (Case 3).

connection.query(sql, function (err,rows){

    //Handle Errors
    if(err){
        //Log The Error & Die
    }

    //If Successful - Log Results For Now (Change To Export Results)
    else {
        //console.log(rows);
        foo = rows;

    }

});

console.log(foo); // Out: undefined

Why can't I access the variable outside of the function?

SOLUTION

Well, the problem here was one of understanding what asynchronicity really is. After chatting with @AmmarCSE and looking at this great question here on SO I understood that I structured my question (and my code, obviously) incorrectly.

I was trying to access a variable that is not defined until the function finishes to run (an SQL query to a remote DB obviously takes longer to finish then running a local script). If I structure my code asynchronically, however, the variable only gets called once the function finishes.

This, as it turns out - is not a problem of variable scope, really, but of variable defining time (not sure if that's the correct terminology for the time in the script where the variables get defined - CS majors, feel free to edit in the correct term).

Anyway, Here is the new code:

runSQL(function(result){

//Do Whatever you want with the results - they're defined!!
console.log(result);
)};

function runSQL(callback){

connection.query(sql, function (err,rows){

        //Handle Errors
        if(err){
            //Log The Error & Die
        }

        //If Successful - Log Results For Now (Change To Export Results)
        else {
            callback(rows);            
        }

    });

}
Community
  • 1
  • 1
Tom Granot
  • 1,840
  • 4
  • 22
  • 52
  • possible duplicate of [What is the scope of variables in JavaScript?](http://stackoverflow.com/questions/500431/what-is-the-scope-of-variables-in-javascript) – TaoPR Jun 13 '15 at 09:34
  • You can, but callbacks don't execute when you think they do. – Dave Newton Jun 13 '15 at 09:35
  • I KInda Pointed That As My Reference. – Tom Granot Jun 13 '15 at 09:36
  • @DaveNewton How So? What Am I Missing Here? – Tom Granot Jun 13 '15 at 09:36
  • I know I answered, but actually, **I** have a question. Shouldnt `foo` above still work because it is a global variable because it was defined without `var`? – AmmarCSE Jun 13 '15 at 09:40
  • @AmmarCSE - That's What I Said! Weird As Hell. – Tom Granot Jun 13 '15 at 09:41
  • Oh, I see my mistake now. The callback is **asynchronous** therefore, when you log `foo` it is `undefined` because it was not defined yet in the callback – AmmarCSE Jun 13 '15 at 09:42
  • So How Can I Be Sure That When I Call The Variable It Will Be Defined? – Tom Granot Jun 13 '15 at 09:44
  • @TomGranot-Scalosub, it depends on the flow of your code. When/why do you need foo? You should restructure your code around the asyncronous nature of the callback. – AmmarCSE Jun 13 '15 at 09:46
  • @AmmarCSE - This is a DB querying module I built to provide me with a certain record for my main app every time the app runs. So, I need to **export** the record from this module to my main module. *However,* I cannot do that from within the function. – Tom Granot Jun 13 '15 at 09:49
  • @TomGranot-Scalosub, you will need to export from within the function. Call `export()` from within the callback itself – AmmarCSE Jun 13 '15 at 09:50
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/80452/discussion-between-ammarcse-and-tom-granot-scalosub). – AmmarCSE Jun 13 '15 at 10:10
  • @TomGranot-Scalosub, join the chat so we can discuss in detail – AmmarCSE Jun 13 '15 at 10:19

3 Answers3

1

When you are in the error callback, it has its own scope defined. Therefore, foo is only visible to that closure and any nested closures. For case 3 you have mentioned in the link

var a = 1;

function four() {
  if (true) {
    var a = 4;
  }

  alert(a); // alerts '4', not the global value of '1'
}

they alert the variable within the correct closure, function four(), even if that variable was defined in the if block, it is visible to its parent function.

However, you are making foo global by not prefixing with var. Yet, logging after the callback results in undefined because at that point, foo was not yet defined. If you log within the error callback it will work but I advise you restructure your code to work with the asynchronous nature of callbacks

connection.query(sql, function (err,rows){

    //Handle Errors
    if(err){
        //Log The Error & Die
     }

    //If Successful - Log Results For Now (Change To Export Results)
    else{
        //console.log(rows);
        foo = rows;

    }
    console.log(foo);
    });
AmmarCSE
  • 30,079
  • 5
  • 45
  • 53
  • OK! But - I Need To Eventually Export That Variable Into A Different Module, And I **Can't** Do That From Within The Block. How Can I Make Sure `foo` Is Defined Outside Of `function` & `connection.query`? – Tom Granot Jun 13 '15 at 09:40
0

if you put a var foo = "something" in somewhere it'd would equal "something". I suppose it didn't go into the else otherwise it'd equal rows... Also is it possible rows is undefined?

Also without using a var foo = anywhere it becomes a global variable if the foo = bit is executed, which is probably not desirable...

Forbesmyester
  • 936
  • 6
  • 15
0
var result= connection.query(sql, function (err,rows){

    //Handle Errors
    if(err){
        //Log The Error & Die
     }

    //If Successful - Log Results For Now (Change To Export Results)
    else{
        //console.log(rows);
        document.foo = rows;

    }

    });

result.on('result', function(){
    console.log(document.foo);
}
David
  • 5,897
  • 3
  • 24
  • 43