2

Here's my issue.

On one side I have a plain object representation of a Mongoose object.

On the other side I have a Mongoose object coming straight from a findOne in the database.

What I am trying to do is check if anything is different between two properties of the two object. Let's consider this kind of model for example:

{
   _id: 'abc',
   id: 'abc',
   things: [{
      _id: 'def',
      id: 'def',
      other_things: [{
        _id: 'ghi',
        id: 'ghi',
        foo: 'bar'
      }]
   }]
}

I want to compare myplainobject.things to mydbobject.things.

But, using underscore, _.isEqual(myplainobject.things, mydbobject.things) always fails.

This is due to ids that are in the first case string and in the other, ObjectID.

While there are a lot of ways to compare an ObjectID to a string, is there an elegant way to compare objects? Or do I have to implement my own solution that would loop through every subdocument and manually compare properties?

Guillaume Flandre
  • 8,936
  • 8
  • 46
  • 54

1 Answers1

2

Since I do no have enough reputation at this point to add a comment to the answer by drinchev, I'll add it here instead. First, use the toObject() method as suggested by drinchev, and then you can use something like the answers from https://stackoverflow.com/a/14368628/3365039 (slightly modified) to ensure the keys come in the same order.

function compareKeys(a, b) {
    var aKeys = Object.keys(a).sort();
    var bKeys = Object.keys(b).sort();

    // Check that the objects contain the same keys.
    if (JSON.stringify(aKeys) !== JSON.stringify(bKeys)) {
        return false
    }

    // Check that the keys in each object contain the same values.
    for (const key in aKeys) {
        if (a[key] !== b[key]) {
            return false
        }
    }

    return true
}

compareKeys(mongooseModel.toObject(), jsObject)
Community
  • 1
  • 1
mgs
  • 41
  • 8