Instantiating new Document in NestJS with mongoose crashes

Viewed 608

So I'm following the NestJS docs on MongoDB, and I'm running into a problem.

Let's say I got this schema

// cat.model.ts
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';

@Schema()
export class Cat extends Document {
  @Prop()
  name: string;
  @Prop()
  info: string;

  constructor(dto: CreateCatDTO) {
    super();
    this.name = dto.name;
    // some algorithm to do stuff which I don't want to happen in the service
    // since it's for the Cat model (SOLID)
    this.info = dto.name + algorithmResultBlah;
  }
}

export const CatSchema = SchemaFactory.createForClass(Cat);

But.. when I instantiate that in the service

// cat.service.ts
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { Cat } from './interfaces/cat.model';

@Injectable()
export class CatsService {
  constructor(@InjectModel("Cat") private readonly catRepository: Model<Cat>) {}

  async create(dto: CreateCatDTO) {
    const cat = new Cat(dto); 
    // I have to make a new instance to do some processing in the model..
    // I don't want to do that in the service based on an interface because clutter
    this.catRepository.create(cat);
  }
}

The code above compiles fine, but when I call the function it gives the following error:

TypeError: Cannot read property 'plugin' of undefined
    at Cat.Document.$__setSchema (~\node_modules\mongoose\lib\document.js:2883:10)
    at new Document (~\node_modules\mongoose\lib\document.js:82:10)
    at new Cat (~\dist\melding\domain\cat.js:7:9)

How can I get this to work? I've been scratching my head (and google) on this for a week now and I have tried so many things.

1 Answers

You need to create an instance of the Mongoose model, not the class instance. This should work

const cat = new this.catRepository(dto);
await cat.save();

or

const cat = await this.catRepository.create(dto);

I suggest you to rename catRepository to CatModel and it'll make it easier to work with. Nest creates models based on the schemas defined in your TS classes and injects these models wherever you need them. That said the class is merely a typing sugar that doesn't really work as a class, it's only used to provide type safety and generate the model's schema.

Related