4

I am trying to write a validation function, that validates my request headers. It returns true if all headers are ok and false if there is something wrong. I execute this function for every (almost) request. The problem is, I don't know how to return the main function in case I use callbacks and setting any flags does not work, due to some issues with variable scope. Everything was good when I was working without callbacks, I just used underscore to query my JSONs. Now I use NeDB and bound to callbacks I cannot get the job done. I tried to use a global "res" variable but the problem is, when I assign the value of parameter "cnt" (0 if token not found, 1 if there is a token) to "res", then the value of "res" is always 1 iteration behind "cnt": i.e.:

request1 (valid): cnt = 1; res = undefined;
request2 (valid): cnt = 1; res = 1;
request3 (invalid): cnt = 0; res = 1;
request4 (valid): cnt = 1; res = 0;

All I want to do is to return the main function with true if "cnt" = 1 and false if "cnt" = 0, either with help of a global variable or using another method.

function validateHeaders(request) {
    if (request.headers.username && request.headers.deviceid) {

        if (...) {
            function getResult(callback) {
                db.tokens.count({...
                }, function (err, cnt) {
                    if (err) {
                        console.log(err);
                    } else {
                        callback(cnt);
                    }
                });
            }

            getResult(function (cnt) {
                res = cnt;
                console.log({
                    count: cnt
                });
            });

            console.log({
                result: res
            });
        } else {
            return false;
        }
    } else {
        return false;
    }
}
3
  • Since the function has an asynchronous function inside and you shouldn't return until this has finished, you need to make your main function validateHeaders asynchronous too, by adding a callback. Commented Oct 1, 2014 at 15:14
  • "asynchronous" means the function is entered into an event queue to be run -- at the earliest -- when the current synchronous function has completed. Thus, the JavaScript engine strictly guarantees that validateHeaders will completely run and return a value before any asynchronous operation begins (such as the callback to db.tokens.count). Commented Oct 1, 2014 at 15:33
  • This is basically a duplicate of How to return the response from an Ajax call? -- simply substitute "Ajax success function" with db.tokens.count. Other similar questions are Understanding Node.js processing order and how to make synchronous call to indexeddb method from javascript Commented Oct 1, 2014 at 15:35

2 Answers 2

2

You can't return a meaningful value like that from a function that performs asynchronous, non-blocking operations inside. What you need to do instead is pass in a callback:

function validateHeaders(request, cb) {
  if (request.headers.username && request.headers.deviceid) {
    if (...) {
      db.tokens.count({
        // ...
      }, function (err, cnt) {
        if (err) {
          cb(err);
        } else {
          cb(null, cnt === 1);
        }
      });
      return;
    }
  }
  cb(null, false);
}

Then use it like:

validateHeaders(req, function(err, success) {
  if (err) throw err; // TODO: improve error handling
  console.log(success);
});
Sign up to request clarification or add additional context in comments.

Comments

0

if you want to use the return value of callback function of nodejs. You can't use it in sync style. you can obey convention of nodejs.

function validateHeaders(request, cb) {
    if (request.headers.username && request.headers.deviceid) {

        if (...) {
            function getResult(callback) {
                db.tokens.count({...
                }, function (err, cnt) {
                    callback(err, cnt);
                });
            }

            getResult(function (err, cnt) {
                if (err) {
                    cb(err);
                } else {
                    if (cnt === 0)
                        cb(null, false);
                    else
                        cb(null, true);                    
                }
            });
        } else {
            cb(null, false)
        }
}

you can use the callback result. Notice: do not use return in async function. use callback to transfer the value. the callback function of nodejs style has 2 arguments. The first is err, the second is result.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.