1

I have a function which basically queries the MongoDB for a credential (simplified):

var query = Credential.findOne({token: token});

return query.exec(function (err, credential) {
    if (err) return null;
    return credential;
});

I need this credential for another query to get associated roles:

router.get('/api/roles', function (req, res) {
   var token = req.headers.authorization || '';
   var cred;

   if (token === '') {
       return res.sendStatus(401);
   }
   getCredential(token).then(function (credential) {
      cred = credential;
   });

   getRoles(cred).then(function(roles) {
      return res.json(roles);
   });
});

Unfortunately, I can't seem to set the local variable cred from within the resolved promise and thus it is undefined. Any idea how to do this?

1 Answers1

2

It looks like you don't quite understand how promises work asynchronously. Your local variable is getting set, but not until after you use it. The order of execution looks something like:

  1. Roles query finishes
  2. Get credential query starts
  3. Get roles query starts
  4. Credential query finishes
  5. Roles query finishes

As you can see, both the credential and roles queries are started simultaneously. The callback that sets cred doesn't get run until the credential query finishes, so that's too late. You can take advantage of promises to fix this.

router.get('/api/roles', function (req, res) {
    var token = req.headers.authorization || '';

    if (token === '') {
        return res.sendStatus(401);
    }

    getCredential(token).then(function (credential) {
        // getRoles returns a promise
        // The next "then()" will be called when this
        // promise is resolved
        return getRoles(credential);
    })
    .then(function(roles) {
        res.json(roles);
    });
});

Now the execution runs like this:

  1. Roles query finishes
  2. Get credential query starts
  3. Credential query finishes
  4. Roles query starts
  5. Roles query finishes and sets the response
Justin Howard
  • 5,504
  • 1
  • 21
  • 48