Reputation: 6289
I am using a combination of filter
, some
, and includes
to return a filtered set of documents in my MongoDB/Node back-end environment.
While I can get this to work in a mock example, when I plug it in to my actual data, I get an error.
This is the key problematic piece of code:
let filteredDocs = docs.filter(doc => doc.branches._id.some(branch => mongoArrBranchID.includes(branch._id)));
When I console.log this out with:
console.log("filteredDocs: ", filteredDocs);
I get:
Reason: TypeError: Cannot read property 'some' of undefined
I've been scratching my head trying to figure out what the issue is here. Why is my mock example working, but not this?
One thought I had was that maybe the issue is that the comparison is made with different types. So then I checked with these two lines of code to make sure the comparison is using Mongo ObjectIDs in both cases (both return true
):
console.log("is param value valid: ", mongoose.Types.ObjectId.isValid(mongoArrBranchID[0])); // returns true
console.log("is doc value valid: ", mongoose.Types.ObjectId.isValid(docs[0].branches[0]._id)); // returns true
So why am I getting the TypeError: Cannot read property 'some' of undefined
error here?
By the way, just so you know what the data looks like, my passed-in filter values when consoled out look like this :
console.log("mongoArrBranchID: ", mongoArrBranchID); // result below
mongoArrBranchID: [ 5ac26645121f0613be08185d, 5ac26645121f0613be08185a ]
And again, this check returns true:
console.log("is param value valid: ", mongoose.Types.ObjectId.isValid(mongoArrBranchID[0])); // returns true
My docs
data looks like this when I console out the first of the docs:
console.log("doc branches: ", docs[0].branches); // result below
doc branches: [{"_id":"5ac26645121f0613be08185a","name":"New York"},{"_id":"5ac26645121f0613be08185d","name":"Los Angeles"},{"_id":"5ac26648121f0613be081862","name":"Charlotte"},{"_id":"5ac2664a121f0613be081869","name":"Chicago"},{"_id":"5ac2664a121f0613be08186e","name":"Seattle"}]
When I console out just the first branches._id value, like so:
console.log("doc branch: ", docs[0].branches[0]._id);
I get:
doc branch: 5ac26645121f0613be08185a
And again, this check on the whether the value is a valid Mongo Object ID returns true:
console.log("is doc value valid: ", mongoose.Types.ObjectId.isValid(docs[0].branches[0]._id)); // returns true
So what's the problem here? Why am I getting this error:
Reason: TypeError: Cannot read property 'some' of undefined
When I do:
let filteredDocs = docs.filter(doc => doc.branches._id.some(branch => mongoArrBranchID.includes(branch._id)));
console.log("filteredDocs: ", filteredDocs);
And for extra clarification, when I use mock data in ScratchJS in Chrome, this works for me:
let docs = [
{
_id: "5ba39a12179b771820413ad8",
name: "Samson",
branches: [{ _id: "3nc26645121f0613be08167r", name: "New York" }, { _id: "3fc26645121f0613be08185d", name: "Los Angeles" }, { _id: "2hc26648121f0613be081862", name: "Seattle" }, { _id: "7jc2664a121f0613be081869", name: "Chicago" }, { _id: "7ju2664a121f0613be08186e", name: "Charlotte" }],
updatedAt: "2018-09-20T13:01:06.709Z",
createdAt: "2018-09-20T13:01:06.709Z"
},
{ _id: "3ya39a12179b771820413af5", name: "Sarah", branches: [{ _id: "3nc26645121f0613be08167r", name: "New York" }, { _id: "5ac26645121f0613be08145d", name: "Miami" }, { _id: "5ac2664a121f0613be08154s", name: "Sacramento" }], updatedAt: "2018-09-20T13:01:06.709Z", createdAt: "2018-09-20T13:01:06.709Z" },
{ _id: "2sa39a12179b771820413gy4", name: "Tim", branches: [{ _id: "1rd26645121d5613be08167h", name: "Denver" }, { _id: "5ac2664a121f0613be08154s", name: "Sacramento" }], updatedAt: "2018-09-20T13:01:06.709Z", createdAt: "2018-09-20T13:01:06.709Z" }
];
let filterValues = ["5ac26645121f0613be08145d", "7ju2664a121f0613be08186e"];
let filteredDocs = docs.filter(doc => doc.branches.some(branch => filterValues.includes(branch._id)));
console.log(filteredDocs);
So what's the difference? Why does it work in the mock example but not with my actual data?
Upvotes: 0
Views: 732
Reputation: 646
It is because docs.branches
is an array, and therefore does not have the _id
attribute you have accessed on it. You should revise your code to the following:
let filteredDocs = docs.filter(doc => doc.branches.some(branch => mongoArrBranchID.includes(branch._id)));
The error you received occurred because accessing an non-existent attribute of an object returns undefined
, so doc.branches._id
returned undefined
, and trying to access an attribute of undefined, some
in this case, throws an error.
EDIT:
I want to clarify that the mistake is you wrote doc.branches._id.some
instead of doc.branches.some
in your code. The issue is the _id
part.
Upvotes: 1