GithubHelp home page GithubHelp logo

Comments (11)

eliellis avatar eliellis commented on April 19, 2024 31

I just want to leave a comment here for anyone who comes across this in the future. For my purposes, I was interested in using multiple models in the schema definitions of each other within pre/post hooks, e.g. I want delete all user posts when a user gets deleted, etc. I found that registering hooks with asynchronous behavior wasn't working with the .forFeature(), did some digging in the documentation, tried forFeatureAsync(), found this issue, and was able to piece together a solution.

You can use .forFeatureAsync() to provide your models, as outlined in the documentation, and inject the other modules into the factory functions you define in the exact same way you would in a service. The only difference being that you do not decorate any schema factory method parameters with@InjectModel, but instead add an entry in the inject array of the forFeatureAsync where the entry is defined by using the getModelToken() method from mongoose.util.ts mentioned in the testing portion of the documentation.

Here is a short example:

// models/index.ts
import { AsyncModelFactory, getModelToken } from '@nestjs/mongoose';
import { UserSchemaFactory } from './user/user';
import { PostSchemaFactory } from './posts/post';

const UserModelToken = 'User';
const PostModelToken = 'Post';

export const MONGOOSE_MODELS: AsyncModelFactory[] = [
  { name: PostModelToken, useFactory: PostSchemaFactory }, // must also define a model with the same name (PostModelToken)
  {
    name: UserModelToken,
    useFactory: UserSchemaFactory,
    inject: [getModelToken(PostModelToken)],
  },
]

// user.schema.ts
const UserSchema = new Schema({ ... });
export const UserSchemaFactory = (
  postModel: Model<UserPost>, // postModel will be injected
): Schema<any> => {
  // remove all user posts when a user is deleted
  UserSchema.pre<User>('remove', async function() {
    await postModel.deleteMany({ author: this._id });
  });

  return UserSchema;
};

from mongoose.

pozniakas avatar pozniakas commented on April 19, 2024 7

I created a solution to have Mongoose middleware with keeping OOP principles, but I believe that the functions of decorators could be improved. At least, the final view looks great.

import { Injectable } from '@nestjs/common';
import { MongoMiddleware, MongoSubscriber } from '#MongoDB';

...

@Injectable()
@MongoSubscriber(BeautifulMessageModel)
export class BeautifulMessageSubscriber {
  constructor(private beautifulService: BeautifulService) {}

  @MongoMiddleware('post', 'save')
  async informAboutNewMessage(message: BeautifulMessage) {
    this.beautifulService.letsDoSomethingFun(message);
  }

  @MongoMiddleware('pre', 'save')
  async informAboutNewMessage(message: BeautifulMessage) {
    this.beautifulService.letsDoSomethingSad(message);
  }
}

// Make this middleware to work with specifying this class as a provider:
//  providers: [BeautifulMessageSubscriber],
import type { Schema } from 'mongoose';

type Model = {
  name: string;
  schema: Schema;
};

export function MongoSubscriber({ schema }: Model) {
  return function _MongoSubscriber<T extends { new (...args: any[]): {} }>(constr: T) {
    return class extends constr {
      schema: Schema;
      constructor(...args: any[]) {
        super(...args);
        this.schema = schema;
        const methods = Object.getOwnPropertyNames(constr.prototype).filter((v) => v !== 'constructor');
        methods.forEach((method) => this[method]());
      }
    };
  };
}
import type { MongooseDocumentMiddleware } from 'mongoose';

export function MongoMiddleware(type: 'pre' | 'post', middleware: MongooseDocumentMiddleware) {
  return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
    const originalMethod = descriptor.value;
    descriptor.value = function (...args: any[]) {
      const method = originalMethod.bind(this);
      this.schema[type](middleware, async function (document, next) {
        if (type === 'pre') {
          await method(this);
          return document();
        }
        await method(document);
        next();
      });
    };
  };
}

from mongoose.

joe307bad avatar joe307bad commented on April 19, 2024 5

I came across this as I had a similar issue/need. I solved it using @kamilmysliwiec suggestion.

Instead of using the normal @nestjs/mongoose method of establishing a schema, I created a custom provider and injected the service I needed to construct that schema. (For my situation, it was injecting the roles to construct the User schema). Here is my provider/module:

export const UserSchemaProvider = {
  provide: 'User',
  useFactory: (access: ac.AccessControl): mongoose.Model<User> => {
    const roles = access.getRoles();

    const UserSchema = BaseSchema({
      firstName: { type: String, required: true },
      lastName: { type: String, required: true },
      userName: { type: String, unique: true, required: true },
      password: { type: String, required: true },
      roles: { type: [{ type: String, enum: roles }], default: 'user', required: true }
    });

    UserSchema.pre<User>('save', function (next) {
      const user = this;
      if (user.password) {
        bcrypt.hash(user.password, 10, function (err, hash) {
          if (err) {
            return next(err);
          }
          user.password = hash;
          next();
        });
      }
    });

    return mongoose.model('User', UserSchema);
  },
  inject: ['AccessControl']
};


@Module({
  controllers: [UserController],
  providers: [UserService, AuthService, UserSchemaProvider],
})
export class UserModule {
}

And then in my UserService, I inject the dependency to utilize the model so I can save a user :

@Injectable()
export class UserService {

  private db = DatabaseService;

  constructor(
    @Inject('User') private readonly userModel: Model<User>,
    private auth: AuthService) { }

  async create(userDto: UserDto): Promise<JwtResponse> {
    const user = new this.userModel(userDto);
    return this.db.save(user).then(newUser => this.auth.createToken(newUser));
  }

}

Some things to note that took me a bit to figure out:

  • The inject property takes an array of strings of the tokens you set up for the provider you are trying to inject. I was using an actual reference to the provider which didn't seem to work.
  • My custom provider returns a mongoose.Model as opposed to a mongoose.Schema. This took me a bit to figure out. I believe its because instead of using InjectModel from @nestjs/mongoose, are are instead using regular 'ol Inject.

from mongoose.

tnte avatar tnte commented on April 19, 2024 3

I came across the same problem. I tackled it using NestJS Event-System to decouple source code considering responsibilities of classes.

First, I've written a global module MongoEventsModule which has a provider that takes the EventEmitter-Instance by dependency injection and registers hooks on schemas. Those hooks emit events.

import { Global, Injectable, Module } from '@nestjs/common';
import { EventEmitter2 } from '@nestjs/event-emitter';
import * as mongoose from 'mongoose';

abstract class MongoEvent<TDocument extends mongoose.Document> {
  event: string;
  doc: TDocument;

  protected constructor(event: string, doc: TDocument) {
    this.event = event;
    this.doc = doc;
  }
}

export class MongoPostSaveEvent<TDocument extends mongoose.Document> extends MongoEvent<TDocument> {
  constructor(modelName: string, doc: TDocument) {
    super(modelName + '.post.save', doc);
  }
}

export class MongoPostRemoveEvent<TDocument extends mongoose.Document> extends MongoEvent<TDocument> {
  constructor(modelName: string, doc: TDocument) {
    super(modelName + '.post.remove', doc);
  }
}

@Injectable()
export class MongoEvents {
  constructor(private readonly eventEmitter: EventEmitter2) {}

  public forSchema<TDocument extends mongoose.Document>(modelName: string, schema: mongoose.Schema<TDocument>){
    const eventEmitter = this.eventEmitter;
    schema.post('save', async (doc) => {
      const event = new MongoPostSaveEvent(modelName, doc);
      eventEmitter.emit(event.event, event);
    });
    schema.post('remove', async (doc) => {
      const event = new MongoPostRemoveEvent(modelName, doc);
      eventEmitter.emit(event.event, event);
    });
    return schema;
  }
}

@Global()
@Module({
  providers: [MongoEvents],
  exports: [MongoEvents],
})
export class MongoEventsModule {}

As the documentation suggests I then register MongoDB Schemas as follows:

@Module({
  imports: [
    MongooseModule.forFeatureAsync([
      {
        name: SomeModel.name,
        useFactory: (events: MongoEvents) =>  events.forSchema(SomeModel.name, SomeModelSchema), // register events on schema
        inject: [MongoEvents],
      },
    ]),
  ],
....
})
export class SomeOtherModule {}

And where I'm interessted in Mongo-Events I define EventListeners like

  @OnEvent('SomeModel.post.remove')
  onSomeModelPostRemove(payload: MongoPostRemoveEvent<SomeModelDocument>) {
     // do sth. like deleting depending docs.
  }

from mongoose.

jardosa avatar jardosa commented on April 19, 2024 2

I just want to leave a comment here for anyone who comes across this in the future. For my purposes, I was interested in using multiple models in the schema definitions of each other within pre/post hooks, e.g. I want delete all user posts when a user gets deleted, etc. I found that registering hooks with asynchronous behavior wasn't working with the .forFeature(), did some digging in the documentation, tried forFeatureAsync(), found this issue, and was able to piece together a solution.

You can use .forFeatureAsync() to provide your models, as outlined in the documentation, and inject the other modules into the factory functions you define in the exact same way you would in a service. The only difference being that you do not decorate any schema factory method parameters with@InjectModel, but instead add an entry in the inject array of the forFeatureAsync where the entry is defined by using the getModelToken() method from mongoose.util.ts mentioned in the testing portion of the documentation.

Here is a short example:

// models/index.ts
import { AsyncModelFactory, getModelToken } from '@nestjs/mongoose';
import { UserSchemaFactory } from './user/user';
import { PostSchemaFactory } from './posts/post';

const UserModelToken = 'User';
const PostModelToken = 'Post';

export const MONGOOSE_MODELS: AsyncModelFactory[] = [
  { name: PostModelToken, useFactory: PostSchemaFactory }, // must also define a model with the same name (PostModelToken)
  {
    name: UserModelToken,
    useFactory: UserSchemaFactory,
    inject: [getModelToken(PostModelToken)],
  },
]

// user.schema.ts
const UserSchema = new Schema({ ... });
export const UserSchemaFactory = (
  postModel: Model<UserPost>, // postModel will be injected
): Schema<any> => {
  // remove all user posts when a user is deleted
  UserSchema.pre<User>('remove', async function() {
    await postModel.deleteMany({ author: this._id });
  });

  return UserSchema;
};

As of March 2023, this doesn't seem to work. Here is my code:

// Attachment Schema
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';

import { HydratedDocument, Types } from 'mongoose';

import Paginate from 'common/models/Paginate.type';

export type AttachmentDocument = HydratedDocument<Attachment>;

@Schema({ timestamps: true })
export class Attachment {
  _id: Types.ObjectId;

  @Prop({
    type: Types.ObjectId,
    index: true,
    required: true,
    refPath: 'source',
  })
  referenceId: Types.ObjectId;

  @Prop({ type: String, required: true, enum: ['Comment'] })
  source: string;

  @Prop({ required: true })
  fileUrl: string;
  @Prop({ required: true })
  fileType: string;
  @Prop({ required: true })
  fileName: string;
  @Prop({ required: true })
  fileThumbnail: string;
}

export const AttachmentSchema = SchemaFactory.createForClass(Attachment);

export interface AttachmentPaginate extends Paginate {
  data: Attachment[];
}

export const AttachmentFactory = () => {
  const attachmentSchema = AttachmentSchema;

  return attachmentSchema;
};
// Comment Schema

import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';

import { HydratedDocument, Model, Types } from 'mongoose';

import Paginate from 'common/models/Paginate.type';
import { AccountUser } from 'services/account/schema/accountUser.schema';
import {
  Attachment,
  AttachmentDocument,
} from 'services/attachment/schema/attachment.schema';

export type CommentDocument = HydratedDocument<Comment>;

@Schema({
  timestamps: true,
  toObject: { virtuals: true },
  toJSON: { virtuals: true },
})
export class Comment {
  _id: Types.ObjectId;

  @Prop({ type: Types.ObjectId, ref: Comment.name, default: null })
  parentId?: Types.ObjectId;

  @Prop({ type: Types.ObjectId })
  referenceId?: string;

  @Prop()
  source: string;

  @Prop({ required: true })
  content: string;

  @Prop({
    type: Types.ObjectId,
    index: true,
    required: true,
    ref: AccountUser.name,
  })
  userId: Types.ObjectId;

  @Prop({ required: true })
  userSource: string;
}

export const CommentSchema = SchemaFactory.createForClass(Comment);

export interface CommentPaginate extends Paginate {
  data: Comment[];
}

export const CommentFactory = (attachmentModel: Model<AttachmentDocument>) => {
  const commentSchema = CommentSchema;
  commentSchema
    .virtual('comments', {
      ref: Comment.name,
      localField: '_id',
      foreignField: 'parentId',
      count: true,
    })
    .get((total: number) => {
      return {
        total,
      };
    });

  commentSchema
    .virtual('attachments', {
      ref: Attachment.name,
      localField: '_id',
      foreignField: 'referenceId',
    })
    .get((attachments: AttachmentDocument) => {
      return attachments;
    });

  commentSchema.pre('findOneAndDelete', async function (next) {
    const doc = await this.model.findOne(this.getFilter());
    await this.model.deleteMany({ parentId: doc._id });
    await attachmentModel
      .deleteMany({
        referenceId: doc._id,
      })
      .exec();
    return next();
  });
  return commentSchema;
};
// Comment Imports File

import { MongooseModule, getModelToken } from '@nestjs/mongoose';
import AccountModule from 'services/account';
import { Comment, CommentFactory } from './schema/comment.schema';
import { Attachment } from 'services/attachment/schema/attachment.schema';

export default [
  AccountModule,
  MongooseModule.forFeatureAsync([
    {
      name: Comment.name,
      useFactory: CommentFactory,
      inject: [getModelToken(Attachment.name)],
    },
  ]),
];

This is the error i'm getting

[Nest] 71605  - 03/14/2023, 10:42:35 AM   ERROR [ExceptionHandler] Nest can't resolve dependencies of the CommentModel (DatabaseConnection, ?). Please make sure that the argument AttachmentModel at index [1] is available in the MongooseModule context.

Potential solutions:
- Is MongooseModule a valid NestJS module?
- If AttachmentModel is a provider, is it part of the current MongooseModule?
- If AttachmentModel is exported from a separate @Module, is that module imported within MongooseModule?
  @Module({
    imports: [ /* the Module containing AttachmentModel */ ]
  })

from mongoose.

crisscaucott avatar crisscaucott commented on April 19, 2024 1

[Nest] 71605 - 03/14/2023, 10:42:35 AM ERROR [ExceptionHandler] Nest can't resolve dependencies of the CommentModel (DatabaseConnection, ?). Please make sure that the argument AttachmentModel at index [1] is available in the MongooseModule context.

Potential solutions:

  • Is MongooseModule a valid NestJS module?
  • If AttachmentModel is a provider, is it part of the current MongooseModule?
  • If AttachmentModel is exported from a separate @module, is that module imported within MongooseModule?
    @module({
    imports: [ /* the Module containing AttachmentModel */ ]
    })

I faced the same problem (dependency error on CommentModel in your case), and trying different approaches, based on your Comment import file, this should be work:

// Comment Imports File

import { MongooseModule, getModelToken } from '@nestjs/mongoose';
import AccountModule from 'services/account';
import { Comment, CommentFactory } from './schema/comment.schema';
import { Attachment } from 'services/attachment/schema/attachment.schema';

export default [
  AccountModule,
  MongooseModule.forFeatureAsync([
    {
      name: Comment.name,
      useFactory: CommentFactory,
      imports: [MongooseModule.forFeature([{ name: 'Attachment', schema: AttachmentSchema }])], // THIS
      inject: [getModelToken(Attachment.name)],
    },
  ]),
];

from mongoose.

kamilmysliwiec avatar kamilmysliwiec commented on April 19, 2024

There's no built-in solution, but you should be able to do it manually by providing a custom component, as described here: https://docs.nestjs.com/fundamentals/dependency-injection (useValue and as a value, you can use a mongoose schema).

from mongoose.

vitordhers avatar vitordhers commented on April 19, 2024
    const UserSchema = BaseSchema({
      firstName: { type: String, required: true },
      lastName: { type: String, required: true },
      userName: { type: String, unique: true, required: true },
      password: { type: String, required: true },
      roles: { type: [{ type: String, enum: roles }], default: 'user', required: true }
    });

@joe307bad
Just out of curiosity, where did this BaseSchema come from? I've tried to replicate the code but that object(function?) seems to be missing, although I imported * from mongoose.

from mongoose.

pahakrai avatar pahakrai commented on April 19, 2024

I am facing the same issue but the below code seems to work @crisscaucott did you made the code work with module import though just curious

@Module({
  imports: [
    // OrderModule,
    MongooseModule.forFeatureAsync([
      {
        name: OrderName,
        useFactory: () => OrderSchema,
      },
      {
        name: OrderItemName,
        useFactory: OrderItemSchemaFactory,
        inject: [getModelToken(OrderName)],
      },
    ]),
  ],
  controllers: [OrderItemController],
  providers: [OrderItemService],
  exports: [OrderItemService],
})
export class OrderItemModule {
  constructor(private readonly RPCService: RPCService) {
    this.RPCService.RPCObserver(
      'ORDER_ITEM_UPDATE',
      () => ({}) 
    );
  }
}

from mongoose.

achim2 avatar achim2 commented on April 19, 2024

These solutions are fine if I use only in one module, but if I implement them in several modules, the second one won't work. I have a category, user, product schema. If I want remove a category then it has to remove the categories from the product and I want to remove a product then it has to remove the products from the user wishlist, etc. The second one won't work. Why? If I comment out one of the module then the another will work

product.module.ts

import { Module } from '@nestjs/common';
import { ProductsService } from './products.service';
import { ProductsController } from './products.controller';
import { getModelToken, MongooseModule } from '@nestjs/mongoose';
import { Product, ProductSchema, productSchemaFactory } from './schemas/product.schema';
import { User, UserSchema } from '../users/schemas/user.schema';
import { FileService } from '../file/file.service';

@Module({
  imports: [
    // MongooseModule.forFeature([{ name: Product.name, schema: ProductSchema }]),
    MongooseModule.forFeatureAsync([
      {
        name: Product.name,
        inject: [getModelToken(User.name)],
        imports: [MongooseModule.forFeature([{ name: User.name, schema: UserSchema }])],
        useFactory: productSchemaFactory,
      },
    ]),
  ],
  controllers: [ProductsController],
  providers: [ProductsService, FileService],
})
export class ProductsModule {}

part of product.schema.ts

export const productSchemaFactory = (model: Model<UserDocument>) => {
  // ProductSchema.pre('findOneAndDelete', async function () {
  //   const id = this.getFilter()?._id;
  //   await model.updateMany(
  //     {},
  //     {
  //       $pull: {
  //         wishlist: { $in: [id] },
  //       },
  //     },
  //   );
  // });

  console.log('model:', model);

  ProductSchema.pre('save', async function () {
    console.log('ProductSchema save');
  });

  ProductSchema.pre('findOneAndDelete', async function () {
    console.log('ProductSchema findOneAndDelete');
  });
  return ProductSchema;
};

category.module.ts

import { Module } from '@nestjs/common';
import { CategoriesService } from './categories.service';
import { CategoriesController } from './categories.controller';
import { getModelToken, MongooseModule } from '@nestjs/mongoose';
import { Category, CategorySchema, categorySchemaFactory } from './schemas/category.schema';
import { Product, ProductSchema } from '../products/schemas/product.schema';

@Module({
  imports: [
    // MongooseModule.forFeature([{ name: Category.name, schema: CategorySchema }]),
    MongooseModule.forFeatureAsync([
      {
        name: Category.name,
        inject: [getModelToken(Product.name)],
        imports: [MongooseModule.forFeature([{ name: Product.name, schema: ProductSchema }])],
        useFactory: categorySchemaFactory,
      },
    ]),
  ],
  controllers: [CategoriesController],
  providers: [CategoriesService],
})
export class CategoriesModule {}

part of category.schema.ts

export const categorySchemaFactory = (model: Model<ProductDocument>) => {
  // CategorySchema.pre('findOneAndDelete', async function () {
  //   const id = this.getFilter()?._id;
  //   await model.updateMany(
  //     {},
  //     {
  //       $pull: {
  //         categoryRefs: { $in: [id] },
  //         categories: { $in: [id] },
  //       },
  //     },
  //   );
  // });

  console.log('model:', model);

  CategorySchema.pre('save', async function () {
    console.log('CategorySchema save');
  });

  CategorySchema.pre('findOneAndDelete', async function () {
    console.log('CategorySchema findOneAndDelete');
  });
  return CategorySchema;
};

Why can't the 2 modules work together?

from mongoose.

vitusan avatar vitusan commented on April 19, 2024

I just want to leave a comment here for anyone who comes across this in the future. For my purposes, I was interested in using multiple models in the schema definitions of each other within pre/post hooks, e.g. I want delete all user posts when a user gets deleted, etc. I found that registering hooks with asynchronous behavior wasn't working with the .forFeature(), did some digging in the documentation, tried forFeatureAsync(), found this issue, and was able to piece together a solution.
You can use .forFeatureAsync() to provide your models, as outlined in the documentation, and inject the other modules into the factory functions you define in the exact same way you would in a service. The only difference being that you do not decorate any schema factory method parameters with@InjectModel, but instead add an entry in the inject array of the forFeatureAsync where the entry is defined by using the getModelToken() method from mongoose.util.ts mentioned in the testing portion of the documentation.

For those struggling with the error @jardosa mentioned, i found a sollution to it. We don't actually need to inject the token itself. The function has a this that returns a Model interface which contains a $model method that we can use to retrieve the right model. So we register the module just like any other, using .forFeature(). At the bottom of the Schema, we can define the hooks.

In my specific case, i needed to check previous documents and generate an auto incremental prop in the document being saved to the DB.

product.schema.ts

@Schema({ timestamps: true, collection: Product.name.toLowerCase() })
export class Product {
  @Prop({ enum: ProductTypeEnum })
  type: ProductTypeEnum;

  @Prop({ unique: true })
  displayId: string;

  @Prop({ enum: ProductStatusEnum, default: ProductStatusEnum.ACTIVE })
  status: ProductStatusEnum;

  @Prop({})
  name: string;

  @Prop({})
  description: string;

  @Prop({ enum: Object.keys(languages) })
  language: TLanguageCode;

  @Prop({ enum: Object.keys(countries) })
  country: TCountryCode;

  @Prop()
  images: string[];

  @Prop({ enum: ProductCategoryEnum })
  category: ProductCategoryEnum;

  @Prop()
  coin: string;

  @Prop()
  reembursementTerm: number;

  @Prop()
  formOfPayment: string;

  @Prop()
  price: string;

  @Prop({ type: [{ type: Types.ObjectId, ref: User.name.toLowerCase() }] })
  affiliates: User[];

  @Prop({ type: Types.ObjectId, ref: User.name.toLowerCase() })
  producer: User;

  @Prop({ type: [{ type: Types.ObjectId, ref: User.name.toLowerCase() }] })
  coproducers: User[];

  @Prop({ type: [ProductAffiliateRequestSchema] })
  affiliateRequests: ProductAffiliateRequest[];

  @Prop({ type: [ProductCoproducerRequestSchema] })
  coproducerRequests: ProductCoproducerRequest[];
}
export const ProductSchema = SchemaFactory.createForClass(Product);

ProductSchema.pre('save', async function (this, next) {
  const product = await this.$model<Model<Product>>(Product.name)
    .findOne()
    .sort({ createdAt: -1 });

  if (!product) {
    this.displayId = '1';
  } else {
    this.displayId = (parseInt(product.displayId) + 1).toString();
  }
  next();
});

database.module.ts

@Module({
  imports: [
    MongooseModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: (configService: ConfigService) => ({
        uri: configService.get(EnviromentVariablesEnum.NOSQL_CONNECTION_STRING),
        useNewUrlParser: true,
        connectionFactory: (connection) => {
          // eslint-disable-next-line @typescript-eslint/no-var-requires
          connection.plugin(require('mongoose-autopopulate'));
          return connection;
        },
      }),
      inject: [ConfigService],
    }),

    MongooseModule.forFeature([
      { name: Client.name, schema: ClientSchema },
      { name: Tfa.name, schema: TfaSchema },
      { name: Verification.name, schema: VerificationSchema },
      { name: PixControl.name, schema: PixControlSchema },
      { name: TicketControl.name, schema: TicketControlSchema },
      { name: Account.name, schema: AccountSchema },
      { name: Movement.name, schema: MovementSchema },
      { name: Kyc.name, schema: KycSchema },
      { name: Fee.name, schema: FeeSchema },
      { name: User.name, schema: UserSchema },
      { name: Notification.name, schema: NotificationSchema },
      { name: Product.name, schema: ProductSchema },
    ]),
  ],
  exports: [MongooseModule],
})
export class DatabaseModule {}

from mongoose.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.