Git Product home page Git Product logo

Comments (6)

gitkrakel avatar gitkrakel commented on September 25, 2024

I am also able to reproduce with Document.prototype.$clone instead of Ramda's clone by modifying an existing unit-test to use a subdocument array:

  it.only('modification of test "$clone() (gh-11849)"', async function() {
    const schema = new mongoose.Schema({
      subDocArray: [{
        name: {
          type: String,
          validate: {
            validator: (v) => v !== 'Invalid'
          }
        }
      }]
    });
    const Test = db.model('Test', schema);

    const item = await Test.create({ subDocArray: [{ name: 'Test' }] });

    const doc = await Test.findById(item._id);
    const clonedDoc = doc.$clone();

    // This assertion fails
    assert.deepEqual(clonedDoc.subDocArray[0], doc.subDocArray[0]);
  });

from mongoose.

IslandRhythms avatar IslandRhythms commented on September 25, 2024
const mongoose = require('mongoose');
const assert = require('assert');

const testSchema = new mongoose.Schema({
  subDocArray: [{
    name: {
      type: String,
      validate: {
        validator: (v) => v !== 'Invalid'
      }
    }
  }]
});

const Test = mongoose.model('Test', testSchema);

async function run() {
  await mongoose.connect('mongodb://localhost:27017');
  await mongoose.connection.dropDatabase();

  await Test.create({ subDocArray: [{ name: 'Test' }] });
  const doc = await Test.findOne();
  const cloneTrooper = doc.$clone();

  assert.deepEqual(cloneTrooper.subDocArray[0], doc.subDocArray[0]);
  console.log('done');
}

run();

from mongoose.

vkarpov15 avatar vkarpov15 commented on September 25, 2024

I repro-ed OP's post using the following:

    const R = require('ramda');
    const mongoose = require('mongoose');

const OrganizationModel = mongoose.model('Organization', mongoose.Schema({ members: [{ user: 'ObjectId' }] }));
const UserModel = mongoose.model('User', mongoose.Schema({ members: ['ObjectId'] }));

void async function main() {
    await mongoose.connect('mongodb://127.0.0.1:27017/mongoose_test');
    let foundOrgModel = await OrganizationModel.findOne({});
    if (!foundOrgModel) {
        // create user
        const user = await UserModel.create({})
        // create org
       foundOrgModel = await OrganizationModel.create({ members: [{ user: user._id }] })
    }

    foundOrgModel = await OrganizationModel.findOne({})
    const members = R.clone(foundOrgModel.members);
    console.log(members[0]._id.toString()) // crashes
}();

@gitkrakel your issue looks unrelated to OP's, but we'll take a look at that as well

from mongoose.

vkarpov15 avatar vkarpov15 commented on September 25, 2024

@Axosoft-Ashley the R.clone() issue comes down to the fact that, in Mongoose 5.x, the ObjectId class from the bson library stored its data in an id property. In Mongoose 8.x, the ObjectId class from the bson library stores its data in a Symbol('kId') property. And, internally, R.clone() uses a for/in loop to iterate the object to clone, which doesn't loop over symbols.

I'll do some more digging to see if there's a way we can reconcile these two. But given that R.clone() isn't extensible, it looks like our only options are to either 1) update the bson library to make the raw data associated with an ObjectId stored in an own non-symbol property on the ObjectId instance, 2) update Ramda to clone symbols. For example, updating Ramda's _clone() function to use the following seems to work:

      for (var key of Object.keys(value).concat(Object.getOwnPropertySymbols(value))) {
        if (Object.prototype.hasOwnProperty.call(value, key)) {
          copiedValue[key] = deep ? _clone(value[key], true, map) : value[key];
        }
      }

from mongoose.

vkarpov15 avatar vkarpov15 commented on September 25, 2024

Actually, it looks like [email protected] (just released today) fixes this issue, so R.clone() works fine now, following script outputs the ObjectId as a string if Mongoose installs [email protected]:

    const R = require('ramda');
    const mongoose = require('mongoose');

const OrganizationModel = mongoose.model('Organization', mongoose.Schema({ members: [{ user: 'ObjectId' }] }));
const UserModel = mongoose.model('User', mongoose.Schema({ members: ['ObjectId'] }));

void async function main() {
    await mongoose.connect('mongodb://127.0.0.1:27017/mongoose_test');
    let foundOrgModel = await OrganizationModel.findOne({});
    if (!foundOrgModel) {
        // create user
        const user = await UserModel.create({})
        // create org
       foundOrgModel = await OrganizationModel.create({ members: [{ user: user._id }] })
    }

    foundOrgModel = await OrganizationModel.findOne({})
    const members = R.clone(foundOrgModel.members);
    console.log(members[0]._id.toString()) // crashes
}();

Related issue here: mongodb/js-bson#643. So @Axosoft-Ashley please re-run npm install, and update your package-lock.json to use [email protected] if you have a package-lock.json.

from mongoose.

Axosoft-Ashley avatar Axosoft-Ashley commented on September 25, 2024

@vkarpov15 I tested in my playground and it did appear to fix the issue with 6.4.0 of bson! Thank you 😄

from mongoose.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.