Muirik
Muirik

Reputation: 6289

Using `filter`, `some`, and `includes` Not Working as Expected in Filtering Docs

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

Answers (1)

Tomer Aberbach
Tomer Aberbach

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

Related Questions