I'm currently working on integrating Typegoose with GrqphQL, MongoDB, and Nest.js for a project. My goal is to create a mutation that will allow users to create a post. I have set up the model, service, and resolver for a simple Post. However, when I attempt to run the mutation to create a Post, I encounter the following error:
PostModel validation failed: sections: Cast to Array failed for value:
[ [Object: null prototype] { title: 'section 1', body: [ 'section test lalal' ], code: [ "console.log('hello world!)" ], image: [ 'kanow.svg' ] } ]
at path "sections"
I have tried using ref and itemsRefs for both class and string values. You can find more information about this in the Typegoose arrayProp documentation. After creating a new PostModel
and logging every property, I noticed that the sections
array is empty, even though it shouldn't be. The JSON within postInput
looks like this:
[Object: null prototype] {
title: 'refactored post',
image: 'rest.jpg',
tags: [ 'ref, ref' ],
sections: [
[Object: null prototype] {
title: 'section 1',
body: [Array],
code: [Array],
image: [Array]
}
]
}
Based on this JSON data, everything seems correct, so this should not be the cause of the error.
I would appreciate any insights on what I might be doing wrong and why it's not working as expected. Below you'll find some relevant code snippets. Feel free to ask if you need any additional information in the comments.
GraphQL mutation:
mutation {
createPost(postInput: {
image: "rest.jpg",
title: "refactored post"
tags: ["ref, ref"]
sections: [{
title: "section 1"
body: ["section test lalal"]
code: ["console.log('hello world!)"]
image: ["kanow.svg"]
}]
}) {
_id
title
tags
sections {
title
body
code
image
}
}
}
post.service.ts:
@Injectable()
export class PostsService {
constructor(@InjectModel(PostModel) private readonly postModel: ReturnModelType<typeof PostModel>) {
}
async create(postInput: CreatePostInput): Promise<DocumentType<PostModel>> {
const createdPost: DocumentType<PostModel> = new this.postModel(postInput);
return await createdPost.save();
}
...
}
post.model.ts:
@ObjectType()
export class PostModel {
@Field(() => ID)
readonly _id: ObjectId;
@Field()
@prop({required: true})
title: string;
@Field()
@prop({nullable: true})
image: string;
@Field(() => [String])
@arrayProp({items: String})
tags: string[];
@Field(() => [SectionModel])
@arrayProp({ref: 'SectionModel'})
sections: Ref<SectionModel>[];
}
section.model.ts:
@ObjectType()
export class SectionModel {
@Field()
@prop({ required: true })
title: string;
@Field(() => [String])
@arrayProp({ items: String })
body: string[];
@Field(() => [String])
@arrayProp({ items: String })
code: string[];
@Field(() => [String])
@arrayProp({ items: String })
image: string[];
}
create-post.input.ts:
@InputType()
export class CreatePostInput {
@Field()
readonly title!: string;
@Field()
readonly image!: string;
@Field(() => [String])
readonly tags!: string[];
@Field(() => [CreateSectionInput])
readonly sections!: CreateSectionInput[];
}
UPDATE 1
I found that passing an empty array inside the sections body allows me to create a post without any issues. Here's an example query:
mutation {
createPost(postInput: {
image: "newly created.jpg",
title: "newly created"
tags: ["newly created, ref"]
sections: []
}) {
_id
image
title
tags
sections {
title
body
code
image
}
}
}