0

I am trying to get results from my "Books.find" and push it into my books array. I want to then res.send it.

I suspect this has something to do with some kind of asynchronous and scope rubbish.

What's the solution?

This is currently my code.

exports.timeline = function(req, res) {
    var Followers = mongoose.model('Follow');
    Followers.find({'follower': req.user.username}, function(err, followerResult) {
        var name = [req.user.username];
        var books = [];

        function addName(username) {
            name.push(username);
        }

        for(var user in followerResult) {
            addName(followerResult[user]['followed']);
        }

        function getDataByUsername(username) {
            function addBookArray(result) {
                books.push(result);
                return result;
            }

            var Books = mongoose.model('Book');
            Books.find({'username': username}).exec(function (err, result) {
                addBookArray(result);
            });
        }

        for(var usernames in name) {
            getDataByUsername(name[usernames]);
        }

        console.log(books);
        res.send(books);
    });
}
chridam
  • 100,957
  • 23
  • 236
  • 235
Techius
  • 9
  • 5
  • Can you [edit] your question to add the schema definitions for the `Followers` and `Books` models as well as your expected result from a given sample input? – chridam Sep 27 '18 at 13:10
  • Dupe of https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron – JohnnyHK Sep 27 '18 at 13:30

3 Answers3

0

You're right, the problem is that Find is asynchronous and you send your response before you receive the result.

To deal with this kind of issues, you have several choices:

  • The powerful package Async to organize your async loops
  • The aggregation of MongoDB to let your DB join your data
Paradise228
  • 717
  • 3
  • 16
0

Node Js is asynchronous . Your code is never wait for your query result.

Following are some options you can try :

Promise example :-

Promise.all([qry1, qry2]).then(res=>{ console.log(res)  }).catch(err=>{console.log(err);})

here qry1 and qry2 are your mongo query

Dheeman
  • 1
  • 2
0

If you don't want to work with the async package, you can try to work with the $in functionality of mongoose and mongodb. As in, you get the list of users, and then find the list of books whoose userid is inside the user list. Something along the line of :

exports.timeline = function(req, res) {
var Followers = mongoose.model('Follow');
Followers.find({'follower': req.user.username}, function(err, followerResult) {
    var name = [req.user.username];
    var books = [];

    function addName(username) {
        name.push(username);
    }

    for(var user in followerResult) {
        addName(followerResult[user]['followed']);
    }
    Books.find({"username" : { $in: name }}).exec(function (err, books) {
       console.log(books);
       res.send(books);
    });
});
}

Hope this helps.