Запрос нескольких коллекций в проблеме определения объема MongoDB

Я пытаюсь сделать запрос к двум отдельным коллекциям, используя 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 ответ

Решение

Вам необходимо создать область, которая фиксирует текущее значение 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);
});
Другие вопросы по тегам