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

Mongoose casts wrong data type on property with options and type property #11199

Closed
Cartman720 opened this issue Jan 8, 2022 · 4 comments
Closed
Labels
confirmed-bug We've confirmed this is a bug in Mongoose and will fix it. interop issue issue with interop between Mongoose and another npm module that is not a Mongoose prod dependency
Milestone

Comments

@Cartman720
Copy link

Cartman720 commented Jan 8, 2022

Do you want to request a feature or report a bug?

bug

What is the current behavior?

I am using @nestjs/mongoose class schema definition, However when I retrieve document from database, mongoose converts values such as string, number to Document.

@Schema({
  timestamps: true,
  toObject: {
    virtuals: true,
  },
  toJSON: {
    virtuals: true,
  },
})
export class BlogArticle {
  @Prop({
    type: String,
    require: true,
    trim: true,
  })
  title: string;

  @Prop(String)
  description: string;

  @Prop(String)
  thumbnail: string;

  @Prop(
    raw({
      image: {
        type: String,
        default: null,
      },
      label: {
        type: String,
        default: '',
      },
    }),
  )
  banner: any;

  @Prop({
    type: String,
    default: '',
  })
  content: string;

  @Prop({
    type: String,
    unique: true,
    sparse: true,
  })
  slug: string;

  @Prop({
    type: mongoose.Schema.Types.ObjectId,
    ref: User.name,
  })
  author: UserDocument;

  @Prop(Boolean)
  isVisible: boolean;

  @Prop(Date)
  publishedAt: Date;

  get estimatedTime() {
    return getTextReadingTime(this.content);
  }
}

export const BlogArticleSchema = SchemaFactory.createForClass(BlogArticle);

BlogArticleSchema.loadClass(BlogArticle);

On above schem you can see that content property is a string with default property.
However you can see on the screenshot of VSCode debugger, that retrieved data is a ``Documentobject, hence I can't use JS built-in string methods i.e.match`, `split` etc.

unknown

I have debugged @nestjs/mongoose SchemaFactory and did found that it creates valid Mongose schema, so I don't think this is related to external package, rather it's a bug in mongoose itself.

Attaching debugger screenshot for SchemaFactory.

tempsnip

But when I set @Prop(String) to `content property I get valid string, howerver this isn't viable for my case, because I want to use mongoose options for properties.

What is the expected behavior?
I would expect to get string value with option @Prop({ type: String, default: '' })

What are the versions of Node.js, Mongoose and MongoDB you are using? Note that "latest" is not a version.

Mongoose: 6.1.5
Mongo: 4.4

@vkarpov15 vkarpov15 added this to the 6.1.8 milestone Jan 9, 2022
@IslandRhythms IslandRhythms added the needs repro script Maybe a bug, but no repro script. The issue reporter should create a script that demos the issue label Jan 10, 2022
@IslandRhythms IslandRhythms added help This issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessary needs repro script Maybe a bug, but no repro script. The issue reporter should create a script that demos the issue and removed needs repro script Maybe a bug, but no repro script. The issue reporter should create a script that demos the issue help This issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessary labels Jan 19, 2022
@IslandRhythms
Copy link
Collaborator

Could you please provide all the code to reproduce this issue. I am having a hard time attempting to reproduce based on a block of code and screenshots.

@Cartman720
Copy link
Author

Hi @IslandRhythms,

Here the repo with reproduction.

https://github.com/Cartman720/nestjs-mongoose-bug

With NestJS team we could find out that whenever we provide @Prop(Symbol) to class property it converts all string properties to Document Objects, even the instance of mongoose connections outside of @nestjs/mongoose becomes corrupted, thus taking into account that problem is global and not tied to NestJS I assum this may be a mongoose issue.

@IslandRhythms IslandRhythms added confirmed-bug We've confirmed this is a bug in Mongoose and will fix it. and removed needs repro script Maybe a bug, but no repro script. The issue reporter should create a script that demos the issue labels Jan 20, 2022
vkarpov15 added a commit that referenced this issue Jan 23, 2022
@vkarpov15
Copy link
Collaborator

@Cartman720 we took a look and the workaround is the same as in #10807 (comment) . Replace @Prop(String) with @Prop({ type: String }) and your script runs fine. @Prop(Date) makes NestJS do something strange like set String.type = String. Another fix is to delete String.type after schema declaration:

BlogArticleSchema.loadClass(BlogArticle);
// @ts-ignore
delete String.type;

We added a workaround and the fix will be in v6.1.8. However, we still recommend doing @Prop({ type: String }) instead of @Prop(String) always, because the latter makes NestJS modify JavaScript globals in a strange way that we haven't been able to figure out yet.

@vkarpov15 vkarpov15 reopened this Jan 23, 2022
@vkarpov15 vkarpov15 added the interop issue issue with interop between Mongoose and another npm module that is not a Mongoose prod dependency label Jan 23, 2022
@vkarpov15
Copy link
Collaborator

Opened an issue with nestjs/mongoose about this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
confirmed-bug We've confirmed this is a bug in Mongoose and will fix it. interop issue issue with interop between Mongoose and another npm module that is not a Mongoose prod dependency
Projects
None yet
Development

No branches or pull requests

3 participants