'Why model has undefined state with repository pattern?

I'm trying to use repository pattern with TypeScript Now I have base.repository that implements all of the functions that I need, I made it a generic type, and I wanna pass the model while injecting it in constructor, but for some reason, while passing the value, I have undefined state of the particular model, what am I doing wrong?

In the console.log() it shows me that the model is undefined while in file register.service.ts it shows me also undefined, but I passed it as generic.

register.service.ts

import { BaseRepository } from "../repositories/base.repository";
import { Creator } from '../data/models/Creator'
import { RegisterDto } from "../types/dtos/register.dto";
import { Injectable } from '@nestjs/common'
import { RegisterMapper } from '../mappers/register.mapper'
import { errors } from '../errors'
import { mailer } from '../utils/nodemailer'

@Injectable()
export class RegisterService {
    constructor(
      private readonly repository: BaseRepository<Creator>,
      private readonly mapper: RegisterMapper
    ) { }

    async createAccount (doc: RegisterDto) {
      const emailExist = await this.existByEmail(doc.email)
      if (emailExist) {
        return errors.EMAIL_EXIST()
      }
      const created = await this.repository.create(this.mapper.toDomain(doc))
      await mailer(doc.email)
      return created
    }

    private async existByEmail(email: string): Promise<boolean> {
      console.log(email)
      console.log(this.repository)
      const response = await this.repository.get({ email })
      return !!response.email;
    }
}

base.repository.ts

import { ModelType } from '@typegoose/typegoose/lib/types'
import { DuplicateKeyError } from '../errors/DuplicateKeyError'
import { DocumentNotFoundError } from '../errors/DocumentNotFoundError'
import { Model } from 'mongoose'
import { Inject, Injectable, Optional } from '@nestjs/common'

@Injectable()
export class BaseRepository<T = any> {
    constructor(
        @Optional() @Inject('MODEL') private Model: any
    ) { }

    async create (object): Promise<T> {
        const Model = this.Model
        console.log(Model)
        const uniqueKey = Model.getUniqueKey ? Model.getUniqueKey() : null
        if (uniqueKey && object[uniqueKey]) {
            const criteria = {
                [uniqueKey]: object[uniqueKey]
            }
            const existing = await Model.findOne(criteria)
            if (existing) {
                throw new DuplicateKeyError(Model, criteria)
            }
        }

        const model = new Model(object)
        return model.save()
    }

    async update (criteria, object, options = {}) {
        const Model = this.Model

        const uniqueKey = Model.getUniqueKey ? Model.getUniqueKey() : '_id'

        const data = { ...object }
        delete data[uniqueKey]
        delete data.createdAt

        return this.updateRaw(criteria, { $set: { ...data } }, options)
    }

    async updateRaw (criteria, data, options = {}) {
        const query = this._getDbQuery(criteria, options)
        const result = await this.Model.findOneAndUpdate(query, data, { new: true, ...options })

        if (!result) {
            throw new DocumentNotFoundError(this.Model, query)
        }

        return result
    }

    async save (modelInstance) {
        return modelInstance.save()
    }

    async get (criteria, options: any = {}): Promise<T | undefined> {
        console.log(Model)
        const promise = await this.Model.findOne(this._getDbQuery(criteria, options)).exec()

        if (options.select) {
            promise.select(options.select)
        }

        return promise
    }

    async find (criteria, options): Promise<ReturnType<ModelType<T>['find']>> {
        return this.Model.find(this._getDbQuery(criteria, options))
    }

    async resolve (criteria): Promise<T> {
        return this.Model.resolve(this._getDbQuery(criteria))
    }

    async count (query) {
        return this.Model.countDocuments(this._getDbQuery(query))
    }

    async delete (criteria) {
        return this.Model.remove(this._getDbQuery(criteria))
    }

    _getDbQuery (criteria, options: any = {}) {
        if ('getDbQuery' in criteria) {
            const dbQuery = criteria.getDbQuery(options)
            return 'find' in dbQuery
                ? dbQuery.find
                : dbQuery
        } else {
            return criteria
        }
    }

}

What should I do to get the actual model in this repository?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source