I am building a web application using TypeScript, Node JS and MongoDB. I am using Typegoose, https://www.npmjs.com/package/@typegoose/typegoose for interacting with MongoDB. Now, I am trying to get Typegoose/ mongoose to automatically generate object ID for sub-document model. You can see the dummy code below.
I have the models as follow
import { Types } from 'mongoose';
import { getModelForClass, prop } from '@typegoose/typegoose';
class PageContract {
@prop({ required: true, type: String })
public title!: string;
@prop({ required: false, type: String })
public description?: string;
@prop({ required: false, type: String })
public externalLink?: string;
@prop({ required: true, type: Date, default: Date.now() })
public createdAt!: Date;
}
export class SubPage extends PageContract {
@prop({ required: true, type: Types.ObjectId })
public _id!: Types.ObjectId;
}
export class Page extends PageContract {
@prop({ required: false, type: Array })
public subPages?: SubPage[];
@prop({ required: false, type: Date })
public publishedAt!: Date;
@prop({ required: false, type: Date })
public draftedAt!: Date;
@prop({ required: false, type: Date })
public unpublishedAt!: Date;
}
export const PageModel = getModelForClass(Page);
export const SubPageModel = getModelForClass(SubPage);
As you can see in the code snippet above, Page has many SubPage models. I am creating page with sub-pages as below.
export const createPage = ({
title,
description,
externalLink,
subPages,
status
}: SavePagePayload): Promise<DocumentType<Page>> => {
const docSubPages: SubPage[] = [];
if (subPages && subPages.length > 0) {
subPages.every(({ title, description, externalLink }) => {
const subPage = new SubPage();
subPage._id = new Types.ObjectId();
subPage.title = title;
subPage.description = description;
subPage.externalLink = externalLink;
docSubPages.push(subPage);
});
}
const statusFields = getNextStatusTimestamps(status);
return PageModel.create({
...statusFields,
title,
description,
externalLink,
subPages: docSubPages
});
};
As you can see in the code, I have to explicitly generate object id for each sub page as follow because Typegoose does not automatically generates it for me.
subPage._id = new Types.ObjectId();
How can I get Typegoose to automatically generate object ID for sub-document model?
You are explicitly overwriting the default
_idbehavior if you add a@propto a automatically generated property. The fix is to remove the@propdecorator line unless you need to change the type.PS: i have also updated the typegoose documentation to better explain this case in Change _id Type.
dont ever declare your array type with the generic
Arraytype, this will result in aMixedarray, read Array Types & Fields.(currently you are basically saying that property is a array, but without any validation)