Search code examples
javascriptnode.jsmongodbmongoosemongoose-schema

[[[Number]]] does not want to save my [[]] array correctly


I have a triple nested array defined in mongoose. When I try to initialize it with a 2 level deep empty array, it adds a third level. See the following code:

import mongoose, { Schema } from 'mongoose';

const foos = mongoose.model(`FooModel`, new Schema({ numbers: [[[Number]]] }));
const oneFoo = await foos.create({ numbers: [[]] });
console.log(oneFoo.numbers);

Expected: [[]], Actual: [[[]]]

The interesting thing is that it doesn't happen with a 2 level deep array:

const foos = mongoose.model(`FooModel`, new Schema({ numbers: [[Number]] }));
const oneFoo = await foos.create({ numbers: [] });
console.log(oneFoo.numbers);

Expected: [], Actual: []

Any ideas on why this is not working, and is there any workaround ?

Versions:

"mongodb": "3.5.4",
"mongoose": "5.9.22",

EDIT: This was a bug fixed in 5.9.23:


Solution

  • The Why:

    Before mongoose v5.9.2(i.e v5.9.1 and below), mongoose would actually behave the way you expect. However, an issue was raised concerning how mongoose handles typecasting for nested arrays(Github Link), I believe the fix for that issue is what caused the changed behavior you are experiencing.

    The Fix:

    As recommended in the issue thread here, set the castNoneArrays option to false.

    import mongoose, { Schema } from 'mongoose';
    
    mongoose.Schema.Types.Array.options.castNonArrays = false;
    
    const foos = mongoose.model(`FooModel`, new Schema({ numbers: [[[Number]]] }));
    const oneFoo = await foos.create({ numbers: [[]] });
    console.log(oneFoo.numbers);  // Outputs: [[]]