13

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
  • 330
  • 2
  • 3
  • 15
  • 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

12

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
  • 2,311
  • 2
  • 12
  • 26
  • 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
4

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,846
  • 1
  • 12
  • 20
  • 1
    This didn't work, I have edited my original post to show what happens when I use your code – user9650710 Dec 25 '19 at 05:25
  • But why does that happen.. I mean when we do not store data in a variable and just directly print it out it prints the returned object and on the other hand after passing it to variable prints the document fetched in the required format.. Can anybody explain? – Pranshu_Taneja Dec 10 '22 at 06:16
1

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
  • 330
  • 2
  • 3
  • 15