Reputation: 4406
I have this model in Mongoose and NodeJS:
const VisitorSchema = new Schema({
visits: [{date: Date, path: String, details: String}],
// ...
});
And this code:
// Get all visitors.
VisitorSchema.statics.getAllVisitors = function() {
try {
// Return all users.
return Visitor.find()
.sort({created: -1})
.exec();
} catch (err) {
console.log(err);
}
};
// Check and print new users.
VisitorSchema.statics.checkPaths = async function() {
console.log("Checking paths...");
let visitors = await this.getAllVisitors();
for (let visitor of visitors) {
try {
for (let v of visitors.visits) {
// ...
}
} catch (e) {
console.log(e);
console.log(Object.prototype.toString.call(visitor.visits));
throw(e);
}
}
};
Running this function unexpectedly throws:
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
....
I also checked the MongoDB object in the mongo shell and the sub-document visits
for the relevant document is an array and seems OK:
> db.visitors.findOne({_id: ObjectId("...")})
{
"_id" : ObjectId("..."),
"visits" : [
{
"_id" : ObjectId("..."),
"date" : ISODate("..."),
"path" : "/"
},
...
]
}
How can an Array object not be iterable?
Upvotes: 0
Views: 2138
Reputation: 1703
An array is always iterable in JS. Pay attention to the rows in the visitors
collection, which may lack the visits
property. If that property is not an array in MongoDB (this is allowed because MongoDB is a NoSQL database) it will still be cast to an empty array from your model definition.
In your specific case, you have a typo:
for (let v of visitors.visits) // plural
should probably be
for (let v of visitor.visits) // singular
Upvotes: 1