Skip to content
New issue

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

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

Already on GitHub? # to your account

Nested arrays using of result in the incorrect schema type #14416

Closed
2 tasks done
forivall opened this issue Mar 6, 2024 · 4 comments · Fixed by #14447
Closed
2 tasks done

Nested arrays using of result in the incorrect schema type #14416

forivall opened this issue Mar 6, 2024 · 4 comments · Fixed by #14447
Labels
enhancement This issue is a user-facing general improvement that doesn't fix a bug or add a new feature
Milestone

Comments

@forivall
Copy link
Contributor

forivall commented Mar 6, 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

7.6.9

Node.js version

20.6.1

MongoDB server version

5.x

Typescript version (if applicable)

5.2.2

Description

With a schema definition of

    const schema = new Schema({
      nums: [{ type: Array, of: Number }],
      tags: [{ type: 'Array', of: String }],
      subdocs: [{ type: Array, of: Schema({ name: String }) }]
    });

the resulting casters result in Mixed rather than the appropriate type.

    assert.equal(schema.path('nums.$').caster.instance, 'Number'); // actually Mixed
    assert.equal(schema.path('tags.$').caster.instance, 'String'); // actually Mixed
    assert.equal(schema.path('subdocs.$').casterConstructor.schema.path('name').instance, 'String'); // casterConstructor is actually a Mixed instance

Steps to Reproduce

See my updated tests at master...forivall:mongoose:forivall/nested-array-of

.patch
From fe53ac241a266afa08a1e5963e7ff53eac18c469 Mon Sep 17 00:00:00 2001
From: Emily M Klassen <forivall@gmail.com>
Date: Tue, 5 Mar 2024 17:50:52 -0800
Subject: [PATCH] test: add test for nested array of issue

---
 test/schema.test.js | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/test/schema.test.js b/test/schema.test.js
index 0df19a65790..d57fb8e528f 100644
--- a/test/schema.test.js
+++ b/test/schema.test.js
@@ -2672,6 +2672,18 @@ describe('schema', function() {
     assert.equal(schema.path('subdocs').casterConstructor.schema.path('name').instance, 'String');
   });
 
+  it('supports `of` for nested array type definition', function() {
+    const schema = new Schema({
+      nums: [{ type: Array, of: Number }],
+      tags: [{ type: 'Array', of: String }],
+      subdocs: [{ type: Array, of: Schema({ name: String }) }]
+    });
+
+    assert.equal(schema.path('nums.$').caster.instance, 'Number');
+    assert.equal(schema.path('tags.$').caster.instance, 'String');
+    assert.equal(schema.path('subdocs.$').casterConstructor.schema.path('name').instance, 'String');
+  });
+
   it('should use the top-most class\'s getter/setter gh-8892', function() {
     class C1 {
       get hello() {

Expected Behavior

The casters should be the correct schema types.

@IslandRhythms IslandRhythms added has repro script There is a repro script, the Mongoose devs need to confirm that it reproduces the issue confirmed-bug We've confirmed this is a bug in Mongoose and will fix it. and removed has repro script There is a repro script, the Mongoose devs need to confirm that it reproduces the issue labels Mar 7, 2024
@IslandRhythms
Copy link
Collaborator

const mongoose = require('mongoose');
const { Schema } = mongoose;
const assert = require('assert');

(async () => {
  const schema = new Schema({
    nums: [{ type: Array, of: Number }],
    tags: [{ type: 'Array', of: String }],
    subdocs: [{ type: Array, of: Schema({ name: String }) }]
  });

  assert.equal(schema.path('nums.$').caster.instance, 'Number'); // actually Mixed
  assert.equal(schema.path('tags.$').caster.instance, 'String'); // actually Mixed
  assert.equal(schema.path('subdocs.$').casterConstructor.schema.path('name').instance, 'String'); // actually Mixed
  console.log('done');
})();

@forivall
Copy link
Contributor Author

forivall commented Mar 8, 2024

quick correction: in the third assert, the casterConstructor is actually an instance of mixed, so it doesnt have a schema property, so it results in the error

  schema.path('subdocs.$').casterConstructor.schema.path('name').instance,
                                                   ^

TypeError: Cannot read properties of undefined (reading 'path')

@vkarpov15 vkarpov15 added this to the 7.6.11 milestone Mar 13, 2024
vkarpov15 added a commit that referenced this issue Mar 20, 2024
fix: array schema definitions with `of` keyword
@vkarpov15 vkarpov15 modified the milestones: 7.6.11, 8.3 Mar 20, 2024
@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 confirmed-bug We've confirmed this is a bug in Mongoose and will fix it. labels Mar 20, 2024
@vkarpov15
Copy link
Collaborator

I took a look and the issue is that we don't support type: Array, of: Number syntax currently. We'll add support for that in 8.3. But for older versions of Mongoose, of is only supported for Maps.

@forivall
Copy link
Contributor Author

forivall commented Mar 20, 2024

Yeah, it's been in the documentation here for a while, and that's how I hit the issue

Example:

// `arr` is an array of numbers.
new Schema({ arr: [Number] });
// Equivalent way to define `arr` as an array of numbers
new Schema({ arr: { type: Array, of: Number } });

(i thought i mentioned that in my original comment, but looks like i missed that. whoops!)

# for free to join this conversation on GitHub. Already have an account? # 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

Successfully merging a pull request may close this issue.

3 participants