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

SchemaArrayOptions looks emptier than other schema options #8389

Closed
NebSehemvi opened this issue Nov 30, 2019 · 4 comments
Closed

SchemaArrayOptions looks emptier than other schema options #8389

NebSehemvi opened this issue Nov 30, 2019 · 4 comments
Labels
enhancement This issue is a user-facing general improvement that doesn't fix a bug or add a new feature
Milestone

Comments

@NebSehemvi
Copy link

NebSehemvi commented Nov 30, 2019

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

Looks like a bug, might be a feature.

What is the current behavior?

After creating some schemas, like this

const Question = new mongoose.Schema({
  category: { name: 'Category', type: mongoose.Types.ObjectId, ref: 'QuestionCategory', required: true },
  likes: [{ name: 'Liked by', type: mongoose.Types.ObjectId, ref: 'User' }],
  tags:  [{ type: String, name: 'Tags' }],
});

I wanted to write a function which gets schema in JSON for frontend with +1 level deep with ref for ObjectId & ObjectId[] document properties, but there's no ref property in array options.

And this is what I get (I've omitted _id & __v in my func):

{
  category: ObjectId {
    path: 'category',
    instance: 'ObjectID',
    validators: [ [Object] ],
    getters: [],
    setters: [],
    options: SchemaObjectIdOptions {
      name: 'Category',
      type: [Function],
      ref: 'QuestionType',
      required: true
    },
    _index: null,
    isRequired: true,
    requiredValidator: [Function (anonymous)],
    originalRequiredValue: true,
    [Symbol(mongoose#schemaType)]: true
  },
  likes: SchemaArray {
    schemaOptions: {
      typeKey: 'type',
      id: true,
      noVirtualId: false,
      _id: true,
      noId: false,
      validateBeforeSave: true,
      read: null,
      shardKey: null,
      autoIndex: null,
      minimize: true,
      discriminatorKey: '__t',
      versionKey: '__v',
      capped: false,
      bufferCommands: true,
      strict: true,
      pluralization: true
    },
    casterConstructor: [Function: ObjectId] {
      schemaName: 'ObjectId',
      get: [Function (anonymous)],
      _checkRequired: [Function (anonymous)],
      _cast: [Function: castObjectId],
      cast: [Function: cast],
      checkRequired: [Function (anonymous)]
    },
    caster: ObjectId {
      path: 'likes',
      instance: 'ObjectID',
      validators: [],
      getters: [],
      setters: [],
      options: [SchemaObjectIdOptions],
      _index: null,
      [Symbol(mongoose#schemaType)]: true
    },
    '$isMongooseArray': true,
    path: 'likes',
    instance: 'Array',
    validators: [],
    getters: [],
    setters: [],
    options: SchemaArrayOptions { type: [Array] },
    _index: null,
    defaultValue: [Function: defaultFn] { '$runBeforeSetters': true },
    [Symbol(mongoose#schemaType)]: true
  },
  tags: SchemaArray {
    schemaOptions: {
      typeKey: 'type',
      id: true,
      noVirtualId: false,
      _id: true,
      noId: false,
      validateBeforeSave: true,
      read: null,
      shardKey: null,
      autoIndex: null,
      minimize: true,
      discriminatorKey: '__t',
      versionKey: '__v',
      capped: false,
      bufferCommands: true,
      strict: true,
      pluralization: true
    },
    casterConstructor: [Function: SchemaString] {
      schemaName: 'String',
      _cast: [Function: castString],
      cast: [Function: cast],
      get: [Function (anonymous)],
      _checkRequired: [Function (anonymous)],
      checkRequired: [Function (anonymous)]
    },
    caster: SchemaString {
      enumValues: [],
      regExp: null,
      path: 'tags',
      instance: 'String',
      validators: [],
      getters: [],
      setters: [],
      options: [SchemaStringOptions],
      _index: null,
      [Symbol(mongoose#schemaType)]: true
    },
    '$isMongooseArray': true,
    path: 'tags',
    instance: 'Array',
    validators: [],
    getters: [],
    setters: [],
    options: SchemaArrayOptions { type: [Array] },
    _index: null,
    defaultValue: [Function: defaultFn] { '$runBeforeSetters': true },
    [Symbol(mongoose#schemaType)]: true
  }
}

What is the expected behavior?

tags.options must contain custom attribute 'name' with value 'Tags'
likes.options must contain custom attribute 'name' with value 'Liked by' and ref attirubte with corresponded ref

I guess it can be fixed in lib\schema\array.js; in some point of function lifecycle there's ref on cast and options, but then it gets omitted.

What are the versions of Node.js, Mongoose and MongoDB you are using? Note that "latest" is not a version.
node: v13.1.0
mongod: v4.2.1
mongoose: v5.7.13

@vkarpov15 vkarpov15 added this to the 5.7.15 milestone Dec 6, 2019
@vkarpov15 vkarpov15 added the has repro script There is a repro script, the Mongoose devs need to confirm that it reproduces the issue label Dec 6, 2019
@vkarpov15
Copy link
Collaborator

vkarpov15 commented Dec 12, 2019

The issue here is that ref isn't an option on the array schematype, it's an option on the ObjectId schematype within the array. For example, if you print out schema.path('likes.$').options, you'll see ref there. We'll add an $embeddedSchemaType property on arrays that lets you easily reference the underlying schematype, but as a workaround you can just use schema.path('likes.$')

See Schema#path() docs.

@vkarpov15 vkarpov15 added enhancement This issue is a user-facing general improvement that doesn't fix a bug or add a new feature and removed has repro script There is a repro script, the Mongoose devs need to confirm that it reproduces the issue labels Dec 12, 2019
@horvbalint
Copy link

Hi @vkarpov15!
I know this is an old issue, but this is the only one I found mentioning the $embeddedSchemaType field. I too want to get the embedded type of an array, but sadly $embeddedSchemaType is not part of the SchemaType typescript interface.
Is this a bug, shold I open an issue for it?

@vkarpov15
Copy link
Collaborator

@horvbalint out of curiousity, why not just get the array's embedded type using schema.path('likes.$') as suggested?

@horvbalint
Copy link

horvbalint commented Aug 12, 2024

@vkarpov15 I am, thanks to your previous answer, but its meaning is not self-explanatory at first glance and it also means I have to pass the schema to my "processField" function to get the field's embedded type. Both of which would be better with $embeddedSchemaType 😄
It's not a huge problem,just ergonomics :)

@vkarpov15 vkarpov15 reopened this Aug 22, 2024
@vkarpov15 vkarpov15 modified the milestones: 5.8.1, 8.5.5, 8.6.1 Aug 22, 2024
@vkarpov15 vkarpov15 modified the milestones: 8.6.1, 8.6.2 Sep 3, 2024
@vkarpov15 vkarpov15 modified the milestones: 8.6.2, 8.7 Sep 10, 2024
vkarpov15 added a commit that referenced this issue Sep 11, 2024
feat(SchemaType): add getEmbeddedSchemaType() method to SchemaTypes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement This issue is a user-facing general improvement that doesn't fix a bug or add a new feature
Projects
None yet
Development

No branches or pull requests

3 participants