0

I'm learning promises, and I'm trying to clean up my nested populates using Q.

Problem: The layers don't run in order, and the resulting data isn't being passed through to each successive layer.

Q().then(layerOne(aggr_data))
  .then(layerTwo)
  .then(layerThree)

function layerOne(aggr_data) {
  var options = {
      path: '_video'
    , model: 'video'
  };
  return model_video.populate( aggr_data, options, function (err, snippet) {
    if (err) return next(err);
    return snippet;
  });
};

function layerTwo(snippet) {
  var commentOptions = {
      path: '_comments._author'
    , model: 'user'
  };
  return model_user.populate(snippet, commentOptions, function (err, popSnippet) {
    if (err) return next(err);
    return popSnippet;
  });
};

function layerThree(popSnippet) {
  var videoOptions = {
      path: '_video._chirps._comments'
    , model: 'comment'
  };
  return model_comment.populate(snippet, videoOptions, function (err, deepSnippet) {
    if (err) return next(err);
    next(deepSnippet);
  });
};
dmr07
  • 1,388
  • 2
  • 18
  • 37
  • IIRC, you shouldn't need to pass any callback to `populate` if you get a promise out anyway. – Bergi Jul 16 '15 at 21:46
  • Do you expect `layerThree` to get use the `snippet` or the `popSnippet` in its function body? – Bergi Jul 16 '15 at 21:47
  • @Bergi, I noticed the error shortly thereafter. Thanks for pointing it out. Also got rid of the callback and it's working beautifully. – dmr07 Jul 18 '15 at 03:14

1 Answers1

2

The layers don't run in order

Your main problem is that you're not passing a callback to the first then, but the result of a call. That Q().then(layerOne(aggr_data)) should be either

Q(aggr_data).then(layerOne).then(…)

or simply

layerOne(aggr_data).then(…)
Bergi
  • 630,263
  • 148
  • 957
  • 1,375