NodeJS Callback Scoping Issue NodeJS Callback Scoping Issue express express

NodeJS Callback Scoping Issue


Short answer - you can't do that without violating the asynchronous nature of Node.js.

Think about the consequences of trying to access result outside of your callback - if you need to use that value, and the callback hasn't run yet, what will you do? You can't sleep and wait for the value to be set - that is incompatible with Node's single threaded, event-driven design. Your entire program would have to stop executing whilst waiting for the callback to run.

Any code that depends on result should be inside the getCompanyId callback:

api.post('/alert', function(request, response) {    var data = JSON.parse(request.body.data);    var token = data.token;    getCompanyId(token, function(err, result) {        //Any logic that depends on result has to be nested in here    });});

One of the hardest parts about learning Node.js (and async programming is general) is learning to think asynchronously. It can be difficult at first but it is worth persisting. You can try to fight and code procedurally, but it will inevitably result in unmaintainable, convoluted code.

If you don't like the idea of multiple nested callbacks, you can look into promises, which let you chain methods together instead of nesting them. This article is a good introduction to Q, one implementation of promises.


If you are concerned about having everything crammed inside the callback function, you can always name the function, move it out, and then pass the function as the callback:

getCompanyId(token, doSomethingAfter); // Pass the function infunction doSomethingAfter(err, result) {    // Code here}


My "aha" moment came when I began thinking of these as "fire and forget" methods. Don't look for return values coming back from the methods, because they don't come back. The calling code should move on, or just end. Yes, it feels weird.

As @joews says, you have to put everything depending on that value inside the callback(s).

This often requires you passing down an extra parameter(s). For example, if you are doing a typical HTTP request/response, plan on sending the response down every step along the callback chain. The final callback will (hopefully) set data in the response, or set an error code, and then send it back to the user.