Запрос нескольких коллекций в проблеме определения объема 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);
});