Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

structuredClone ObjectId #13341

Closed
2 tasks done
Marius-Romanus opened this issue Apr 28, 2023 · 2 comments
Closed
2 tasks done

structuredClone ObjectId #13341

Marius-Romanus opened this issue Apr 28, 2023 · 2 comments
Milestone

Comments

@Marius-Romanus
Copy link

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Mongoose version

7.1.0

Node.js version

18.16.0

MongoDB server version

5.0.6

Typescript version (if applicable)

No response

Description

Hello, when you do a deep clone with structuredClone of an objectId, it stays in an empty object. I'm not sure if it has to do with mongoose or the node.js API

https://nodejs.org/dist/latest-v18.x/docs/api/all.html#all_globals_structuredclonevalue-options
https://developer.mozilla.org/en-US/docs/Web/API/structuredClone

Thanks greetings.

Steps to Reproduce

const mongoose = require('mongoose');
const id = new mongoose.Types.ObjectId();
console.log(id)
console.log(structuredClone(id))

Expected Behavior

No response

@vkarpov15
Copy link
Collaborator

Unfortunately this is limitation with the structuredClone(), structuredClone() doesn't clone non-built-in classes. So ObjectId will always become a plain object.

If you want to clone a Mongoose document, we recommend using Mongoose documents' built-in $clone() method.

If you absolutely need to use structuredClone(), your best bet would be to 1) add a transform option to all ObjectIds, or 2) use the flattenObjectIds option we're adding for v7.2.

Here's how you can use the transform option approach. Just keep in mind that this will apply to every time you call toObject() or toJSON(), unless you call transform: false

    mongoose.ObjectId.set('transform', val => val.toString());
    const schema = new Schema({
      _id: 'ObjectId',
      nested: {
        id: 'ObjectId'
      },
      subdocument: new Schema({}),
      documentArray: [new Schema({})]
    }, { versionKey: false });

    let Test = db.model('Test', schema);

    const doc = new Test({
      _id: new mongoose.Types.ObjectId('0'.repeat(24)),
      nested: {
        id: new mongoose.Types.ObjectId('1'.repeat(24))
      },
      subdocument: {
        _id: new mongoose.Types.ObjectId('2'.repeat(24))
      },
      documentArray: [{ _id: new mongoose.Types.ObjectId('3'.repeat(24)) }]
    });
    assert.deepStrictEqual(doc.toObject({ transform: true }), {
      _id: '0'.repeat(24),
      nested: {
        id: '1'.repeat(24)
      },
      subdocument: {
        _id: '2'.repeat(24)
      },
      documentArray: [{ _id: '3'.repeat(24) }]
    });

Here's how you'll be able to use flattenObjectIds to do the same thing for an individual toObject() call in v7.2:

    const schema = new Schema({
      _id: 'ObjectId',
      nested: {
        id: 'ObjectId'
      },
      subdocument: new Schema({}),
      documentArray: [new Schema({})]
    }, { versionKey: false });

    let Test = db.model('Test', schema);

    const doc = new Test({
      _id: new mongoose.Types.ObjectId('0'.repeat(24)),
      nested: {
        id: new mongoose.Types.ObjectId('1'.repeat(24))
      },
      subdocument: {
        _id: new mongoose.Types.ObjectId('2'.repeat(24))
      },
      documentArray: [{ _id: new mongoose.Types.ObjectId('3'.repeat(24)) }]
    });
    assert.deepStrictEqual(doc.toObject({ flattenObjectIds: true }), {
      _id: '0'.repeat(24),
      nested: {
        id: '1'.repeat(24)
      },
      subdocument: {
        _id: '2'.repeat(24)
      },
      documentArray: [{ _id: '3'.repeat(24) }]
    });

@Marius-Romanus
Copy link
Author

Thank you very much for the answer, currently I use a forEach with a .toString() and that is valid for me.

greetings

vkarpov15 added a commit that referenced this issue May 8, 2023
feat(document): add flattenObjectIds option to toObject() and toJSON()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants