2014-04-24 39 views
0

我想查询两个单独的集合,使用MongoJS(node.js mongodb包装器)来构建一个对象数组,然后使用EJS使用我的视图进行呈现。查询MongoDB范围问题中的多个集合

我遇到的问题似乎与范围界定有关。

function getTeamMembers(projectID){ 

     var members = []; //<-- Instantiate the array of objects I want to return 

     Projects.findOne(
      { _id : mongojs.ObjectId(projectID) }, 
      function(error, result){ 

       /// Loop through the team to get the member's data 
       /// and push it on the members array 

       var team = result.team; //<-- This is an array of objects 

       for(var i = 0; i < team.length; i++){ 

        members[i] = {}; 
        members[i].accountID = team[i].accountID; 
        members[i].status = team[i].status; 

        Accounts.findOne(
          { _id : mongojs.ObjectId(team[i].accountID) }, 
          function(error, doc){ 

           /// The following line produces the error: 
           /// 'Cannot set property name of undefined' 
           members[i].name = doc.name; 

          } 
        ); 

       } 

       response.send(members); 

      } 
     ); 

    } 

我相信,我在实例化正确的位置,以使其可用于任何儿童功能members[]阵列,但我仍然收到此错误:

TypeError: Cannot set property 'name' of undefined

回答

2

您需要创建一个范围捕获i的当前值,因为当您的findOne()回调执行时,循环已经完成并且i=team.length。您还要在填写任何名称之前发送回复。您可能需要使用async模块为您处理此问题。

此:

for(var i = 0; i < team.length; i++){ 

    members[i] = {}; 
    members[i].accountID = team[i].accountID; 
    members[i].status = team[i].status; 

    Accounts.findOne(
      { _id : mongojs.ObjectId(team[i].accountID) }, 
      function(error, doc){ 

       /// The following line produces the error: 
       /// 'Cannot set property name of undefined' 
       members[i].name = doc.name; 

      } 
    ); 

} 

response.send(members); 

变为:

var async = require('async'); 

// .... 

async.each(team, function(teamItem, callback) { 
    var member = { 
    accountID: teamItem.accountID, 
    status: teamItem.status, 
    name: '' 
    }; 
    members.push(member); 

    Accounts.findOne(
      { _id : mongojs.ObjectId(member.accountID) }, 
      function(error, doc) { 
      if (error) 
       callback(error); 
      else { 
       member.name = doc.name; 
       callback(); 
      } 
      } 
); 
}, function(err) { 
    if (err) 
    response.send(500, err.toString()); 
    else 
    response.send(members); 
}); 
+0

王牌。谢谢@mscdex。我不熟悉'async'。似乎从现在开始非常方便。 – AJB