16

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

4
  • You can take reference Commented Dec 25, 2019 at 5:03
  • @Ashok That is referencing collection.find(). I am trying to perform model.find() Commented Dec 25, 2019 at 5:13
  • Anyone know why this is happening? I got the same problem. But it worked fine before Commented Feb 14, 2020 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() Commented Jun 30, 2021 at 20:21

3 Answers 3

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 :)

Sign up to request clarification or add additional context in comments.

2 Comments

.lean() should help. But in this case we can not use .save() method and other such methods.
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 :)
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.

2 Comments

This didn't work, I have edited my original post to show what happens when I use your code
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?
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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.