1

I am trying to create an array of key-value pairs in a dynamic fashion. The values part is fetched from the database inside my routes. This is what I am doing.

   router.get('/account',isAuthenticated, function(req,res){
   var following_users_details = [];

    for (var i = 0;i<req.user.following_users.length;i++)
    {
        var following_user = req.user.following_users[i];// following_users is a field of Array type in my MongoDB database 
        User.findOne({'username' : following_user },
            function(err,user)
            {
                following_users_details.push({
                    username: user.username,
                    profilepic : user.photo,
                    userbio : user.bio
                });
            });
    }
    res.render('users/userAccount',{user:req.user, following_users_details:following_users_details });
});

But when I try to print my array of key-value pairs I get nothing.

for(var i = 0;i<following_users_details.length;i++)
{
    console.log("Username = "+following_users_details[i].username);
    console.log("Username = "+following_users_details[i].profilepic);
    console.log("Username = "+following_users_details[i].userbio);
}

Nothing gets outputted on the console when I try to print the array. I think I am missing something very obvious. Is this the proper way of creating the array or am I doing it in a wrong way?

P.S. - I have already gone through this , this and this, but none of these address my issue directly.

Community
  • 1
  • 1
Aryak Sengupta
  • 1,727
  • 2
  • 18
  • 23

2 Answers2

3

The callback in findOne happens in the future, it is async. You must render inside said callback for the data to exist.

   User.findOne({'username' : following_user },
        function(err,user)
        {
            following_users_details.push({
                username: user.username,
                profilepic : user.photo,
                userbio : user.bio
            });
            res.render('users/userAccount',{user:req.user, following_users_details:following_users_details });
        });
}
MFors
  • 216
  • 1
  • 3
1

A few things, first one that your console.log happens before they come from db.

Second, and better, do not do all the unnecessary calls per user, make just one call for all of this.

router.get('/account',isAuthenticated, function(req,res){
  var following_users_details = [];

  User.find({
    username:
      {$in: req.user.following_users} // assuming this is an array
  }, {
    // select options. This might be done differently though,
    // depending on your MongoDB driver/ORM
    username: true,
    profilepic: true,
    userbio: true
  },
  // callback
  function (err, followedUsers) {
    // only now you have access to users, not before. Now log/send them
    if (err) {/* handle DB error */

    res.render('users/userAccount',{
      user:req.user,
      following_users_details: followedUsers
    });
    // also log them to console.
    followedUsers.forEach(function(followedUser) {
       console.log(JSON.stringify(followedUser, null, 2);
    });
  });
});
Zlatko
  • 18,936
  • 14
  • 70
  • 123