在MongoDB范围界定问题中查询多个集合

时间:2014-04-24 01:10:23

标签: node.js mongodb mongojs

我正在尝试使用MongoJS(node.js mongodb包装器)查询两个单独的集合来构建一个对象数组,然后我将使用EJS使用我的视图进行渲染。

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

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:无法设置未定义的属性“name”

1 个答案:

答案 0 :(得分: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);
});