I am building a web application using MongoDB and NodeJS (Typescript). I am using Typegoose for interacting with mongodb from my application. Now, I am having a problem using nested discriminator especially inserting array of object to the field. Below is my code.
These are my model classes
import {
getModelForClass,
modelOptions,
prop,
Ref
} from '@typegoose/typegoose';
import {Schema, Types} from "mongoose";
import { Page, SubPage } from './page';
export enum AlertMessageType {
primary = 'primary',
info = 'info',
danger = 'danger',
warning = 'warning'
}
export enum ContentType {
htmlBlock = 'html-block',
header = 'header',
codeBlock = 'code-block',
alertMessage = 'alert-message'
}
@modelOptions({
schemaOptions: {
discriminatorKey: 'type',
_id: false,
id: false
}
})
export class PageSectionContent {
@prop({ required: true, type: Schema.Types.ObjectId })
public _id!: Types.ObjectId;
@prop({ type: Schema.Types.String, required: true })
public type!: ContentType;
@prop({ type: Schema.Types.Boolean, required: true, default: true })
public isActive!: boolean;
}
export class AlertMessageContent extends PageSectionContent {
@prop({ type: String, required: false })
public iconPath?: string;
@prop({ type: String, required: true })
public alertType!: AlertMessageType;
@prop({ type: String, required: false })
public title?: string;
@prop({ type: String, required: true })
public message!: string;
}
export class HtmlBlockContent extends PageSectionContent {
@prop({ type: String, required: false })
public title?: string;
@prop({ required: true, type: String })
public content!: string;
}
export class CodeBlockContent extends PageSectionContent {
@prop({ required: true, type: String })
public code!: string;
}
export class HeaderContent extends PageSectionContent {
@prop({ type: String, required: true })
public title?: string;
}
export class PageSection {
@prop({ required: true, type: String })
public title!: string;
@prop({ required: true, ref: () => Page })
public page!: Ref<Page>;
@prop({ required: false, ref: () => SubPage })
public subPage?: Ref<SubPage>;
@prop({
required: true,
type: PageSectionContent,
discriminators: () => [
{
type: HtmlBlockContent,
value: ContentType.htmlBlock
},
{
type: HeaderContent,
value: ContentType.header
},
{
type: CodeBlockContent,
value: ContentType.codeBlock
},
{
type: AlertMessageContent,
value: ContentType.alertMessage
}
],
default: [],
})
public contents!: PageSectionContent[];
@prop({ type: Boolean, required: true, default: true })
public isActive!: boolean;
}
export const PageSectionModel = getModelForClass(PageSection);
As you can see in the code, PageSection class has a discriminators (array) field called contents.
The I tried to create a PageSection document using the following data.
{
title: 'Eaque magnam illo consequatur laboriosam vel natus minima deserunt.',
contents: [
{
_id: new ObjectId("6434984567b1da87aab5f10d"),
type: 'header',
title: 'Aliquid asperiores incidunt eligendi.',
isActive: false
}
],
isActive: false,
page: new ObjectId("6434984567b1da87aab5f106")
}
This is the code
await PageSectionModel.create({
title: section.title,
isActive: section.isActive,
page: page.id,
contents: contentsToInsert
});
I am getting the following error.
'PageSection validation failed: contents: Tried to set nested object field `contents` to array ``'
But instead of passing array to the contents field, when I pass a single object like this, it is not throwing error.
{
_id: new ObjectId("6434984567b1da87aab5f10d"),
type: 'header',
title: 'Aliquid asperiores incidunt eligendi.',
isActive: false
}
But I need to pass the array.
I also tried declaring the discriminator field like this
@prop({
required: true,
type: () => [PageSectionContent],
discriminators: () => [
{
type: HtmlBlockContent,
value: ContentType.htmlBlock
},
{
type: HeaderContent,
value: ContentType.header
},
{
type: CodeBlockContent,
value: ContentType.codeBlock
},
{
type: AlertMessageContent,
value: ContentType.alertMessage
}
],
default: [],
})
public contents!: PageSectionContent[];
It is still throwing the same error. What is wrong with my code and how can I fix it?