5

I am running on .find() query on an existing model. I have used this code in the past and have changed nothing but now all of the sudden it's not working for some reason. I am thinking either MongoDB or MongooseJS updated and the functionality has changed.

var retrieve = function() {
  Repo.find({}, function(err, docs) {
    console.log(docs)
  })
};

retrieve();

returns

[
  model {
    '$__': InternalCache {
      strictMode: true,
      selected: {},
      shardval: undefined,
      saveError: undefined,
      validationError: undefined,
      adhocPaths: undefined,
      removing: undefined,
      inserting: undefined,
      version: undefined,
      getters: {},
      _id: 5e02e91c908f0f086e737189,
      populate: undefined,
      populated: undefined,
      wasPopulated: false,
      scope: undefined,
      activePaths: [StateMachine],
      pathsToScopes: {},
      ownerDocument: undefined,
      fullPath: undefined,
      emitter: [EventEmitter],
      '$options': true
    },
    isNew: false,
    errors: undefined,
    _doc: {
      __v: 0,
      stars: 2,
      id: 1322,
      url: 'url',
      name: 'name',
      _id: 5e02e91c908f0f086e737189
    },
    '$init': true
  },
  model {
    '$__': InternalCache {
      strictMode: true,
      selected: {},
      shardval: undefined,
      saveError: undefined,
      validationError: undefined,
      adhocPaths: undefined,
      removing: undefined,
      inserting: undefined,
      version: undefined,
      getters: {},
      _id: 5e02e92c3f6b72088246c563,
      populate: undefined,
      populated: undefined,
      wasPopulated: false,
      scope: undefined,
      activePaths: [StateMachine],
      pathsToScopes: {},
      ownerDocument: undefined,
      fullPath: undefined,
      emitter: [EventEmitter],
      '$options': true
    },
    isNew: false,
    errors: undefined,
    _doc: {
      __v: 0,
      stars: 2,
      id: 2,
      url: 'url1',
      name: 'name1',
      _id: 5e02e92c3f6b72088246c563
    },
    '$init': true
  }
]

it should return

[{name: 'name', id: 2, url: 'url', stars: 2},
{name: 'name1', id: 1322, url: 'url1', stars: 2}]

I don't know why this is happening

---- edit for Ahsok --- I tried using your code

const retrieve = () => {
  Repo.find({})
  .then(repo => {
    console.log({ repo })
  })
  .catch(error => {
    console.log({ error })
  })
};

And it's still not returning what it needs to be. Now it's returning

{
  repo: [
    model {
      '$__': [InternalCache],
      isNew: false,
      errors: undefined,
      _doc: [Object],
      '$init': true
    },
    model {
      '$__': [InternalCache],
      isNew: false,
      errors: undefined,
      _doc: [Object],
      '$init': true
    }
  ]
}

Which is the same thing it was returning above, just in a slightly different format

user9650710
  • 140
  • 2
  • 11
  • You can take [reference](https://stackoverflow.com/questions/29113210/what-is-return-type-of-db-collection-find-in-mongodb) – Ashok Dec 25 '19 at 05:03
  • @Ashok That is referencing collection.find(). I am trying to perform model.find() – user9650710 Dec 25 '19 at 05:13
  • Anyone know why this is happening? I got the same problem. But it worked fine before – VinoPravin Feb 14 '20 at 11:14
  • If any of the below solutions didn't work for anyone, the issue for me was that my model wasn't defined inside `mongoose.connect()` – avisk Jun 30 '21 at 20:21

3 Answers3

8

This is the expected behavior, Mongoose find query always return an instance of a mongoose i.e what you are getting. There are two ways to handle this:

  1. Convert your response to plain Object on your own:

console.log(docs.toObject())

  1. Let mongoose itself do this for you (Using lean):
Repo.find({}).lean().exec(function(err, docs) {
    console.log(docs);
});

You can read more about lean here

Hope this helps :)

Mohammed Amir Ansari
  • 1,822
  • 2
  • 10
  • 22
  • 1
    .lean() should help. But in this case we can not use .save() method and other such methods. – iatsi Dec 25 '19 at 06:02
  • 1
    Yes that is correct, That is where you can go for the other option, eg. Use your actual instance to update/Save the document & play with the plain Object as a separate variable :) – Mohammed Amir Ansari Dec 25 '19 at 06:12
2

If you are using async function then use this syntax

const retrieve = async () => {
  const repo = await Repo.find({})
  console.log(repo)
};

If you have no idea whats going on up there use this syntax

const retrieve = () => {
  Repo.find({})
  .then(repo => {
    console.log({ repo })
  })
  .catch(error => {
    console.log({ error })
  })
};

You can take and doc ride from here too.

Why this happens Because find return cursor or promise to retrieve _doc from it you need to use the promise. Here the first type solution is popular to clean code.

Ashok
  • 2,583
  • 1
  • 10
  • 18
0

I figured it out. Turned out I had to revert node to a previous version for this to be the default behavior. Using .lean() as Mohammed pointed out would have also worked but I wanted to know why my code was behaving differently than it used to and it turns out that it was caused by a node update.

user9650710
  • 140
  • 2
  • 11