У меня есть эта модель в Mongoose и NodeJS:
const VisitorSchema = new Schema({
visits: [{date: Date, path: String, details: String}],
// ...
});
И этот код:
// Get all visitors.
VisitorSchema.statics.getAllVisitors = function() {
try {
// Return all users.
return Visitor.find()
.sort({created: -1})
.exec();
} catch (err) {
console.info(err);
}
};
// Check and print new users.
VisitorSchema.statics.checkPaths = async function() {
console.info("Checking paths...");
let visitors = await this.getAllVisitors();
for (let visitor of visitors) {
try {
for (let v of visitors.visits) {
// ...
}
} catch (e) {
console.info(e);
console.info(Object.prototype.toString.call(visitor.visits));
throw(e);
}
}
};
Запуск этой функции неожиданно выдает:
Checking paths...
TypeError: visitors.visits is not iterable
at Function.VisitorSchema.statics.checkPaths
[object Array]
5efba3a0a97a823909802df5
(node:23663) UnhandledPromiseRejectionWarning: TypeError: visitors.visits is not iterable
at Function.VisitorSchema.statics.checkPaths
at processTicksAndRejections
....
Я также проверил объект MongoDB в оболочке mongo, а вложенный документ visits
для соответствующего документа представляет собой массив и выглядит нормально:
> db.visitors.findOne({_id: ObjectId("...")})
{
"_id" : ObjectId("..."),
"visits" : [
{
"_id" : ObjectId("..."),
"date" : ISODate("..."),
"path" : "/"
},
...
]
}
Как объект Array не может быть итерируемым?
Вы ссылаетесь на неправильную переменную во втором внутреннем цикле for. for (let v of visitors.visits)
наверное должно быть for (let v of visitor.visits)
.
@Sven Вы правы, и это исправлено. Можете ли вы написать ответ, подчеркнув, что все объекты массива итерабельны, а если нет, то ошибка в другом месте?
@EdisonPebojot Можете ли вы сказать больше?
@Sven прав @miguelmorin, однако вы также можете попробовать это visitors.forEach( ( v ) => { console.info(v.visits.id) })
@secan Только если ОП имел в виду return await Visitor.find().…;
Массив всегда повторяем в JS. Обратите внимание на строки в коллекции visitors
, в которых может отсутствовать свойство visits
. Если это свойство не является массивом в MongoDB (это разрешено, поскольку MongoDB является базой данных NoSQL), оно все равно будет приведено к пустому массиву из определения вашей модели.
В вашем конкретном случае у вас опечатка:
for (let v of visitors.visits) // plural
наверное должно быть
for (let v of visitor.visits) // singular
Разве
getAllVisitors
не следует объявлять асинхронным (VisitorSchema.statics.getAllVisitors = async function() { ... }
)?