Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NestJS - How to create nested schema with decorators

Let's say I want to build the below schema with mongoose:

const userSchema = new Schema({
  name: {
    firstName: String,
    lastName: String
  }
})

How can I do it with NestJS decorators (@Schema() & @Prop())?

I try this method, but no luck:

@Schema()
class Name {
  @Prop()
  firstName: string;

  @Prop()
  lastName: string;
}

@Schema()
class User extends Document {
  @Prop({ type: Name })
  name: Name;
}

I also don't want to use the raw() method.

like image 475
Sinandro Avatar asked Jul 06 '20 18:07

Sinandro


People also ask

How to get rid of @schema () decorator in nestjs?

Try to remove @schema () decorator from the nested "Name", leaving it only at the root of your document. Also remember to extend 'mongoose.Document' at the root level. Show activity on this post. I haven't found this part of NestJS to be flexible enough. A working solution (tested) for me is the following:

What is nestjs?

Custom decorators | NestJS - A progressive Node.js framework Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with TypeScript and combines elements of OOP (Object Oriented Progamming), FP (Functional Programming), and FRP (Functional Reactive Programming).

Is there a way to use mongoose schemas with nestjs?

The other workaround is to use native mongoose for creating your schemas in NestJS, like so: Show activity on this post.

Is it possible to define a type inside a nested schema?

because in nested schema you don't have yo define type INSIDE the prop decorator but only tell that this field is an array and validate the type using TypeScript Thanks for contributing an answer to Stack Overflow!


Video Answer


2 Answers

Here's my method which works great and doesn't involve removing @schema():

// Nested Schema
@Schema()
export class BodyApi extends Document {
  @Prop({ required: true })
  type: string;

  @Prop()
  content: string;
}
export const BodySchema = SchemaFactory.createForClass(BodyApi);

// Parent Schema
@Schema()
export class ChaptersApi extends Document {
  // Array example
  @Prop({ type: [BodySchema], default: [] })
  body: BodyContentInterface[];

  // Single example
  @Prop({ type: BodySchema })
  body: BodyContentInterface;
}
export const ChaptersSchema = SchemaFactory.createForClass(ChaptersApi);

This saves correctly and shows the timestamps when you have that option set on your schema

like image 54
austinthedeveloper Avatar answered Oct 18 '22 03:10

austinthedeveloper


Changes made:

  1. No @Schema decorator for the sub-document class
  2. Sub-document class needs to extend Document from 'mongoose'

user.schema.ts

import { Document } from 'mongoose';

@Schema()
export class User extends Document {
  @Prop({ type: Name })
  name: Name;
}

export const UserSchema = SchemaFactory.createForClass(User);

name.schema.ts

import { Document } from 'mongoose';

export class Name extends Document {
  @Prop({ default: " " })
  firstName: string;

  @Prop({ default: " " })
  lastName: string;
}
like image 5
Samith Bharadwaj Avatar answered Oct 18 '22 04:10

Samith Bharadwaj