It is useful for work with sub-document arrays to have methods like .create or .id
Made a test and the methods are there still available on the components, just not exported by typescript, if someone has some guidance on how that could be implemented I could give it a try!
if you want to use these functions, you have to define the arrays with them, here an example:
// NodeJS: 12.16.2
// MongoDB: 4.2-bionic (Docker)
import { getModelForClass, prop, arrayProp, DocumentType } from "@typegoose/typegoose"; // @typegoose/[email protected]
import * as mongoose from "mongoose"; // [email protected]
class Nested {
@prop({ required: true })
public someprop!: string;
}
class Parent {
@arrayProp({ items: String })
public normalArray!: mongoose.Types.Array<string>;
@arrayProp({ items: Nested })
public documentArray!: mongoose.Types.DocumentArray<DocumentType<Nested>>;
}
const ParentModel = getModelForClass(Parent);
(async () => {
await mongoose.connect(`mongodb://localhost:27017/`, { useNewUrlParser: true, dbName: "verify255", useCreateIndex: true, useUnifiedTopology: true });
const doc = await ParentModel.create({ normalArray: ["hi", "Hello"], documentArray: [{ someprop: "Hello" }, { someprop: "hi" }] });
console.log(doc);
doc.documentArray.create({ someprop: "Another hello" });
doc.normalArray.$pop();
await doc.save();
console.log(doc);
await mongoose.disconnect();
})();
That worked great! quick question, do you think that would make sense to add a custom type on typegoose on charge of that, so you could use it as.
// Considering DocumentArray is a type exported from typegoose
class Parent {
@arrayProp({ items: String })
public normalArray!: DocumentArray<string>; // If primitive, will infer mongoose.Types.Array<string>
@arrayProp({ items: Nested })
public documentArray!: DocumentArray<Nested>; // If class, will infer mongoose.Types.DocumentArray<DocumentType<Nested>>
}
I think that would be a neat addition, and I could try to work on it!
sorry, but this could lead to problems, like custom types
i think the issue is solved, closing it
Sure, thanks for your time on this!
At first I thought that this was working fine, but once deployed I started seeing some issues, looks like the metadata is not recognizing mongoose.Types.DocumentArray as an array, because I get:
WARN You might not want to use option "items" for an non-array @prop type (Account.branches)
WARN Implicitly setting "Mixed" is not allowed! (Account, branches)
INFO TypeError: this.branches.id is not a function
Where my code is
class Account {
@prop({ default: '' })
name: string
@arrayProp({ items: Branch, default: [] })
branches: mongoose.Types.DocumentArray<DocumentType<Branch>>
@Negan1911 thanks for reporting, will be fixed in next version, for now you can overwrite it @prop({}, WhatIsIt.Array)
(fixed in: d2165fecc1c10455d2fdb163d3cc3f79cce96a62)
@hasezoey Before you publish that fix, I've applied your commit using patch-package on the lib/props.js file, and got this error:
{
"errorType": "ObjectExpectedError",
"errorMessage": "Tried to set nested object field `branches` to array `` and strict mode is set to throw.",
"message": "Tried to set nested object field `branches` to array `` and strict mode is set to throw.",
"name": "ObjectExpectedError",
"path": "branches",
"stack": [
"ObjectExpectedError: Tried to set nested object field `branches` to array `` and strict mode is set to throw.",
" at new ObjectExpectedError (/var/task/node_modules/mongoose/lib/error/objectExpected.js:24:11)",
" at SingleNestedPath.cast (/var/task/node_modules/mongoose/lib/schema/SingleNestedPath.js:156:11)",
" at SingleNestedPath.SchemaType.applySetters (/var/task/node_modules/mongoose/lib/schematype.js:1031:12)",
" at SingleNestedPath.SchemaType.getDefault (/var/task/node_modules/mongoose/lib/schematype.js:968:25)",
" at $__applyDefaults (/var/task/node_modules/mongoose/lib/document.js:405:22)",
That is because how mongoose schema types are being interpreted, I think that for subdocuments typegoose is assigning the type and not [type].
I had been trying to track where does that happens but cannot found it.
@Negan1911 currently its always surround as long as whatis is set to WhatIsIt.Array, this error seems to try to set "undefined/null" to property "branches" of some class
If I apply @prop({}, WhatIsIt.Array) I get:
console.warn
You might not want to use option "items" for an non-array @prop type (Account.branches)
I'm guessing but WhatIsIt.ARRAY is 0 and maybe is not being caught on this line?
(Since WhatIsIt.ARRAY equals 0 also equals false).
Replacing if (!kind) with if (kind === null || kind === undefined) fixes this issue.
I'm still looking why when I apply the patch I get that error, which doesn't happen on any other case (it also doesn't happen on jest). Guessing maybe ts-loader is going nuts or something else, will let you know if I found anything useful
EDIT: Forgot to say, I really appreciate the time you are putting on this!
EDIT2: Found the reason why my patch was not working (causing the Tried to set nested object fieldbranchesto array `` error), is not because of this project!
@Negan1911 thanks, this was really an problem - didnt notice
Most helpful comment
@Negan1911 thanks, this was really an problem - didnt notice