0

MongoJS (node.js mongodb ラッパー) を使用して 2 つの個別のコレクションをクエリして、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' を設定できません

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 に答える