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

Using spread operator on a SubDocument does not give the original object that mongoose is wrapping #14912

Open
2 tasks done
tonivuc opened this issue Sep 25, 2024 · 3 comments
Labels
developer-experience This issue improves error messages, debugging, or reporting
Milestone

Comments

@tonivuc
Copy link

tonivuc commented Sep 25, 2024

Prerequisites

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

Mongoose version

8.6.3

Node.js version

20.14.0

MongoDB server version

6.8.0

Typescript version (if applicable)

5.6.2

Description

When using the spread operator on a SingleNested Document (a SubDocument) I get:

{
 _doc: {
  firstName: 'John',
  lastName: 'Doe'
}
 $__ : ...
 $__parent : ...
 $isNew = false
}

But the actual properties of the object Mongoose is wrapping aren't there (unless I look inside _doc)

However, if I do the spread operator on a nested document (Document) I get the original properties of the document.
And by original properties I mean for example this, and none of the Mongoose properties:

{ 
 firstName: 'John',
 lastName: 'Doe'
}

Steps to Reproduce

Create two schemas

const profileSchemaNestedDoc = {
    firstName: { type: String, required: true },
    lastName: { type: String, required: true },
};

const userSchemaNestedDoc = new mongoose.Schema<any>({
    user: {
        profile: profileSchemaNestedDoc,
    },
});

const profileSchemaSubDoc = new mongoose.Schema<any>({
    firstName: { type: String, required: true },
    lastName: { type: String, required: true },
});

const userSchemaSubDoc = new mongoose.Schema<any>({
    user: {
        profile: { type: profileSchemaSubDoc },
    },
});

Create Document instances of these two, such as userWithSubDoc and userWithNestedDoc with the properties set. Then run

const userWSubDoc = { ...userWithSubDoc };
const userWNestedDoc = { ...userWithSubDoc };

Then using a debug tool examine the constants to see what the live objects look like.

You should see that the output of the spread operation is quite different and as described in this issue description.

Expected Behavior

I would expect the spread operator to work the same way on a Document instance and a SingleNested instance ☺️ And at least give me the properties of the object that Mongoose is wrapping.

@tonivuc tonivuc changed the title Destructuring a SingleNested Document does not give the original object that mongoose is wrapping Using spread operator on a SingleNested Document does not give the original object that mongoose is wrapping Sep 25, 2024
@tonivuc tonivuc changed the title Using spread operator on a SingleNested Document does not give the original object that mongoose is wrapping Using spread operator on a SubDocument does not give the original object that mongoose is wrapping Sep 25, 2024
@vkarpov15
Copy link
Collaborator

This is expected behavior, there's unfortunately no good way for spread operator to return a document's properties with the way that Mongoose is currently architected. You should use { ...userWithSubDoc.toObject() }, or just userWithSubDoc.toObject().

This may change in the future if we make documents use proxies, but that is a major change and currently not planned.

@vkarpov15 vkarpov15 added the help This issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessary label Sep 27, 2024
@tonivuc
Copy link
Author

tonivuc commented Sep 28, 2024

Thanks for the reply @vkarpov15! But it works to use the spread operator for Document...? (nested schema). In the VSCode debug tool it says it is a Document.
It's the inconsistency that I find a bit problematic, and I don't think you addressed it in your comment?

This is our actual runtime objects from the two approaches described in the issue
SubDocument/SingleNested:
image

Nested schema (Document):
image

The spread operator works different for them as described above

@vkarpov15
Copy link
Collaborator

Nested paths and subdocuments are different, there's several behavior differences between the two. Spread operator handling is one of them. There's some more info on the difference in our docs.

It is slightly strange that a nested path shows up as a "Document", we'll look into that

@vkarpov15 vkarpov15 reopened this Oct 2, 2024
@vkarpov15 vkarpov15 added this to the 8.6.5 milestone Oct 2, 2024
@vkarpov15 vkarpov15 added developer-experience This issue improves error messages, debugging, or reporting and removed help This issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessary labels Oct 2, 2024
@vkarpov15 vkarpov15 modified the milestones: 8.7.1, 8.7.2 Oct 8, 2024
@vkarpov15 vkarpov15 modified the milestones: 8.7.2, 8.7.3 Oct 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
developer-experience This issue improves error messages, debugging, or reporting
Projects
None yet
Development

No branches or pull requests

2 participants