0

我正在尝试使用 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:无法设置未定义的属性“名称”

4

1 回答 1

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);
});
于 2014-04-24T01:26:19.203 回答