I have this model:
const NeighborSchema = new Schema({
friends: [
{
type: Schema.Types.ObjectId,
ref: "users",
},
],
date: {
type: Date,
default: Date.now,
},
});
module.exports = Neighbor = mongoose.model("neighbor", NeighborSchema);
I am trying to see if a friend exists in friends of all neighbors:
const mongoose = require("mongoose");
const ObjectId = mongoose.Types.ObjectId;
const testIncludes = async () => {
let neighbors = await Neighbor.find();
let friends_ids = [];
neighbors.map((neighbor) => {
const { friends } = neighbor;
friends_ids = [...friends_ids, ...friends];
});
// Returns false for this
const element_to_search = ObjectId("60dcbb29118ea36a4f3ce229");
// Returns false for this
// const element_to_search = "60dcbb29118ea36a4f3ce229";
let is_element_found = friends_ids.includes(element_to_search);
};
// Returns false in both cases
testIncludes();
Even though, element_to_search
was taken directly from list of returned friends_ids
array, when I try to search it using include
, it returns false
for some reason, whether I search it as a String
or as an ObjectId
.
Any idea what's going on?
CodePudding user response:
Array.prototype.includes compares each element against the sample until it finds a match. Objects are considered equal only if they reference the same instance of the class. When you call a constructor const element_to_search = ObjectId("60dcbb29118ea36a4f3ce229");
it creates a new instance which has never been in the array, even if its value is the same.
You need to compare scalars. Strings for example:
friends_ids.map(f => f.toString()).includes("60dcbb29118ea36a4f3ce229");
or cast it strings when you build up the friends_ids
at the first place to avoid the extra loop over the array.