emonigma
emonigma

Reputation: 4406

Array object is not iterable

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

Answers (1)

Yevhenii
Yevhenii

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

Related Questions