Question

I have a problem in a nodeJS app with mongoDB, i'm trying to do a forum and for each topic i want a button to display every sub topics. So i need to get everything in the request:

  • One array with main topics
  • Another map array with ['topic1'] containing sub topics

Without the mapping (not an actual problem) i have this:

    Post.find({'path': path})
    .exec(function (err, posts){
    if(err)
        console.log("Get post list:" + err);
    else
    {
            var sub_posts = new Array; // Second array with sub topics
            for (var i = 0; posts[i]; i++) //Here is the loop for each topic
            {
                var tmp_path = ... // Path and next request works
                Post.find({'path': tmp_path}) // Here is the second request
                .exec(function(err, bis_posts) {
                    if (err) console.log('Error loading subforum');
                    else sub_posts.push(bis_posts); // Affectation fail !!! 
                })
            }
            res.render(... 'post_list': posts, 'sub_posts': sub_posts); // Send result
    }
})}

So i get it's a scope problem and i should use callback but with the loop i can't resolve this problem.

Sorry for my english and thanks for your answers !

Was it helpful?

Solution

I have no idea what you mean by "affectation fail", but it looks like you're calling res.render too early — callbacks are invoked asynchronously after your current context finishes executing, so when you call res.render(...) after your for loop has finished, your Post.find(...)... operations still haven't finished and their callbacks haven't been invoked, so sub_posts will be still empty.

My node.js and Mongo are rusty, so perhaps this isn't the canonical way to do it, but I'd add a counter to track the state of the pending requests and only call res.render when all subposts have been fetched:

var sub_posts = new Array;
var pending = 0;
for (var i = 0; posts[i]; i++)
{
    var tmp_path = ...
    Post.find({'path': tmp_path})
    .exec(function(err, bis_posts) {
        if (err) console.log('Error loading subforum');
        else sub_posts.push(bis_posts);
        pending -= 1;
        if (!pending) {
            // all pending subpost lookups finished, render the response:
            res.render(... 'post_list': posts, 'sub_posts': sub_posts);
        }
    });
    pending += 1;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top