4

Still wrapping my head around callbacks.

What's the proper way to define/return an object from within a callback function?

You can see my 2 console.logs in the following snippet, the one outside of the callback is of course undefined, how do I define it?

In my app.js:

  var tools = require('../models/tools.js');
  app.get('/games', requireAuth, function (req, res) {
    var gameqlist = tools.getMyGameQs(req, function(err, gameqlist){
      console.log(gameqlist); // this is properly defined
      return gameqlist; // not quite right
    });
    console.log(gameqlist); // this is undefined
    res.render('games', {title:'Your Games!', gameqlist : gameqlist});


  });

I have the following utility function which works fine:

tools.js:

var Gameq = require('../models/gameq');

module.exports = {
  getMyGameQs: function (req, callback){
    // find all game queues that a user is in
    Gameq
      .find({
                'game.players.player_id' : req.user.id
                })
      .asc('created_at') // sort by date - get oldest first
      .run(function(err, gameqlist) {
        if(!gameqlist){
          err = 'You are not in any games.';
        }
        return callback(err, gameqlist); 
      });
  }
};
k00k
  • 17,314
  • 13
  • 59
  • 86
  • I have the same problem and found [this](https://stackoverflow.com/questions/25807786/separating-daos-from-controllers-for-reusability-purposes) useful. – arymeo Sep 12 '14 at 19:43

1 Answers1

4

You shouldn't want to do that. Callbacks are supposed to be asynchronous, so there is a chance that the code after the call to getMyGameQs is executed before the callback.

What you should do call "res.render" from inside the callback.

var tools = require('../models/tools.js');
  app.get('/games', requireAuth, function (req, res) {
    var gameqlist = tools.getMyGameQs(req, function(err, gameqlist){
      res.render('games', {title:'Your Games!', gameqlist : gameqlist});
    });
  });
nxt
  • 1,983
  • 12
  • 13
  • Right, which is what I was originally doing, and of course works fine. The problem I'm running into, from a strictly "theory" point of view is that this is something that will be reused in many places as a widget throughout my app. So it's actually rendered by a partial. It just doesn't "feel" right by jamming the main page's res.render inside of this lowly helper function call that may or may not be used for any given route. It just feels like it should be independent of the main flow. Make sense? – k00k Jan 04 '12 at 18:33
  • 2
    You don't have to use an anonymous function inline. If this is something that will be reused elsewhere, then create a named function and pass that into app.get instead. app.get('/games', requireAuth, renderGamesList); – Timothy Strimple Jan 04 '12 at 22:15
  • @k00k You could look into [promises](http://stackoverflow.com/questions/4296505/understanding-promises-in-node-js), that way you can keep the res.render outside the helper functions. – nxt Jan 05 '12 at 06:49