Make a mongodb request in a middleware - nestjs

I would like to make a find request in my db but in my middleware, so I did naturally as in my service and added a constructor for my model but I have this error:
(node:821) UnhandledPromiseRejectionWarning: Error: Nest can't resolve dependencies of the AccountMiddleware (?). Please make sure that the argument AccountModel at index [0] is available in the AppModule context.
Potential solutions:
- If AccountModel is a provider, is it part of the current AppModule?
- If AccountModel is exported from a separate #Module, is that module imported within AppModule?
#Module({
imports: [ /* the Module containing AccountModel */ ]
})
If I remove the constructor I don't get any error so I don't understand how I can declare my model
Here my actual middleware code:
import { Injectable, NestMiddleware } from '#nestjs/common';
import { InjectModel } from '#nestjs/mongoose';
import { Model } from 'mongoose';
import { IAccount } from './interfaces/account.interface';
#Injectable()
export class AccountMiddleware implements NestMiddleware {
constructor(#InjectModel('Account') private readonly accountModel: Model<IAccount>) {}
async use(req: any, res: any, next: () => void) {
next();
}
}
thank you in advance for your help!

It's just as the error says, you need to have access to the Account model in your AppModule because that's where you're binding the middleware. To make sure you have access to this, you need to either import MongooseModule.forFeature([{ name: 'Account', schema: AccountSchema }]) or you need to import a module that already imports the above MongooseModule and exports it

Related

Nestjs modules - shared custom provider is not working

I have a proyect with multiple modules, and all of them need the same provider, then I have used a shared module but I don't know where the mistake is
import { Module } from '#nestjs/common';
import { ChatBot } from './chat-bot';
import { ChatBotImplementation } from './chat-bot.implementation';
#Module({
providers: [{ provide: ChatBot, useClass: ChatBotImplementation }],
exports: [ChatBot],
})
export class SharedModule {}
import { Module } from '#nestjs/common';
import { CoreService } from './core.service';
#Module({
providers: [CoreService],
})
export class CoreModule {}
import { Module } from '#nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { SharedModule } from './shared/shared.module';
import { CoreModule } from './core/core.module';
#Module({
imports: [SharedModule, CoreModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
import { Injectable } from '#nestjs/common';
import { ChatBot } from 'src/shared/chat-bot';
#Injectable()
export class CoreService {
constructor(chatBot: ChatBot) {
chatBot.send('hola');
}
}
When I start the server, it throws this error:
[Nest] 8456 - 29/12/2022, 17:21:08 ERROR [ExceptionHandler] Nest can't resolve dependencies of the CoreService (?). Please make sure that the argument ChatBot at index [0] is available in the CoreModule context.
Potential solutions:
- Is CoreModule a valid NestJS module?
- If ChatBot is a provider, is it part of the current CoreModule?
- If ChatBot is exported from a separate #Module, is that module imported within CoreModule?
#Module({
imports: [ /* the Module containing ChatBot */ ]
})
ChatBot is an abstract class and ChatBotImplementation implements ChatBot abstract class, I have tried with symbol as provide but it don't working either. If I put the provider in the same module that use it then it works, I supose that the misteka should be in the, exports part?
Your CoreModule doesn't have the SharedModule in its imports so it doesn't have access to providers from the SharedModule's exports. Add imports: [SharedModule] to the CoreModule's module metadata and you'll be good to go

How to create custom (separate file) repository in NestJS 9 with TypeORM 0.3.x

This is not a duplicate Q. Please don't mark this as that.
Following is not I want
import { EntityRepository, Repository } from "typeorm";
import { Test } from "./test.model";
import { Injectable } from "#nestjs/common";
#EntityRepository(Test)
export class TestRepository extends Repository<Test> {}
the #EntityRepository decorator is now deprecated.
I also don't want to make a fake repository like in here:
https://stackoverflow.com/a/73352265/5420070
Don't want this either as I've to extract manager from dataSource, I don't want this because I think this is not the best way.
export const UserRepository = dataSource.getRepository(User).extend({
// ^^^^^^^^^^ from where this came from
findByName(firstName: string, lastName: string) {
return this.createQueryBuilder("user")
.where("user.firstName = :firstName", { firstName })
.andWhere("user.lastName = :lastName", { lastName })
.getMany()
},
})
Found above in: https://orkhan.gitbook.io/typeorm/docs/custom-repository#how-to-create-custom-repository
I don't think this is in NestJS context.
What I want
Want to know right way to make custom repository in latest version of NestJS (v9) & TypeORM (v0.3). In #EntityRepository deprecation note, they said that need to extend the repo to create custom repo like someRepo.extend({}). I want to know how to do it in NestJS way
In order to achieve what you want, you could do something like the following.
This solution is inspired by the official NestJS docs related to this topic, with some customization.
Steps to achieve it:
Create your TypeOrm entity as usual, let's say UserEntity (user.entity.ts file)
Create a UserRepository class (user.repository.ts file)
Create a UserService class as usual (user.service.ts file)
Import the UserRepository into your UserService
Update UserModule in order to provide the UserRepository and needed UserEntity
Detailed implementation example
1. user.entity.ts file
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';
#Entity()
export class UserEntity {
#PrimaryGeneratedColumn()
id: number;
#Column()
firstName: string;
#Column()
lastName: string;
#Column({ default: true })
isActive: boolean;
}
2. user.repository.ts file
import { InjectRepository } from '#nestjs/typeorm';
import { Repository } from 'typeorm';
import { UserEntity } from './user.entity';
export class UserRepository extends Repository<UserEntity> {
constructor(
#InjectRepository(UserEntity)
private userRepository: Repository<UserEntity>
) {
super(userRepository.target, userRepository.manager, userRepository.queryRunner);
}
// sample method for demo purposes
async findByEmail(email: string): Promise<UserEntity> {
return await this.userRepository.findOneBy({ email }); // could also be this.findOneBy({ email });, but depending on your IDE/TS settings, could warn that userRepository is not used though. Up to you to use either of the 2 methods
}
// your other custom methods in your repo...
}
3. & 4. user.service.ts file
import { Injectable } from '#nestjs/common';
import { InjectRepository } from '#nestjs/typeorm';
import { UserRepository } from './user.repository';
import { UserEntity } from './user.entity';
#Injectable()
export class UserService {
constructor(
private readonly userRepository: UserRepository, // import as usual
) {}
findAll(): Promise<UserEntity[]> {
return this.userRepository.find();
}
// call your repo method
findOneByEmail(email: string): Promise<UserEntity> {
return this.userRepository.findByEmail({ email });
}
findOne(id: number): Promise<UserEntity> {
return this.userRepository.findOneBy({ id });
}
async remove(id: string): Promise<void> {
await this.userRepository.delete(id);
}
// your other custom methods in your service...
}
5. Updating UserModule (user.module.ts file)
import { Module } from '#nestjs/common';
import { TypeOrmModule } from '#nestjs/typeorm';
import { UserService } from './user.service';
import { UserController } from './user.controller';
import { UserEntity } from './user.entity';
#Module({
imports: [TypeOrmModule.forFeature([UserEntity])], // here we provide the TypeOrm support as usual, specifically for our UserEntity in this case
providers: [UserService, UserRepository], // here we provide our custom repo
controllers: [UserController],
exports: [UserService, UserRepository] // add this only if you use service and/or custom repo within another module/service
})
export class UserModule {}
With this in place, you should be able to import the UserModule in your AppModule and be able to both implement custom methods in the UserRepository and use them in the UserService. You should also be able to call the manager and queryRunnner of the custom repository.
Additional Note
If you need to directly call your UserRepository methods from within another module/service, then update UserModule to export the UserRepository
Hope it helps, don't hesitate to comment.
import { Column, Entity, JoinColumn, ManyToOne, OneToMany } from "typeorm";
import { CustomBaseEntity } from "../core/custom-base.entity";//custom-made
#Entity({name: 'rcon_log', schema: 'dbo'})
export class LogEntity extends CustomBaseEntity{
------------your code-----------
}

Nest can't resolve dependencies of the ~repository

I'm getting a strange error with my nestjs code.
Repository not connected in module file
[ExceptionHandler] Nest can't resolve dependencies of the UserRepository (?). Please make sure that the argument Connection at index [0] is available in the TypeOrmModule context
The current code is this
app.module.ts
import { Module } from '#nestjs/common';
import { TypeOrmModule } from '#nestjs/typeorm';
import connectionOptions from 'ormconfig';
import { UserModule } from './modules';
#Module({
imports: [TypeOrmModule.forRoot(connectionOptions), UserModule],
providers: [],
})
export class AppModule {}
user.module.ts
import { Module } from '#nestjs/common';
import { TypeOrmModule } from '#nestjs/typeorm';
import { UserRepository } from 'src/repositories';
import { UserController } from './user.controller';
import { UserService } from './user.service';
#Module({
imports: [TypeOrmModule.forFeature([UserRepository])],
controllers: [UserController],
providers: [UserService],
})
export class UserModule {}
user.repository.ts
import { User } from '../entities';
import { EntityRepository, Repository } from 'typeorm';
#EntityRepository(User)
export class UserRepository extends Repository<User> {
async findOneById(userId: string) {
return await this.createQueryBuilder()
.where('user_id = :userId', {
userId,
})
.getOne();
}
}
How can I fix it?
From the code you provided, there should be no problem. The only thing that will trigger the error is the ormconfig config you did not provide.
Can you check if you have name: "xxxx" in your ormconfig config like below:
{
name: 'dbname', <-- check if you have name config here
type: 'mysql',
host: 'localhost',
port: 3306,
...
}
There are 2 ways to solve it if you have name in the config:
If there is only ONE database, you can remove the name and use the default name typeorm provides.
If you have multiple databases or you want to preserve the connection name, you will need to specify the name in the code as well to help typeorm to determine which database to work with, see the below changes:
user.module.ts
#Module({
imports: [
TypeOrmModule.forFeature([UserRepository], 'dbname'), // provide the name here
],
controllers: [UserController],
providers: [UserService],
})
export class UserModule {}
user.service.ts
#Injectable()
export class UserService {
constructor(
#InjectRepository(UserRepository, 'dbname') // provide the name here
private usersRepository: UserRepository,
) {}
...
}

NestJS cannot resolve my UsersService dependency why? Is it due to UserModel?

I am trying to learn NodeJS framework. I have initialized a project for that and now I am trying to add authentication to secure the HTTP access. I follows the NestJS documentation but I have the following error when I inject my UsersService in the AuthService:
[Nest] 14876 - 13/04/2020 à 09:26:19 [ExceptionHandler] Nest can't resolve dependencies of the UsersService (?). Please make sure that the argument UserModel at index [0] is available in the AuthModule context.
Potential solutions:
- If UserModel is a provider, is it part of the current AuthModule?
- If UserModel is exported from a separate #Module, is that module imported within AuthModule?
#Module({
imports: [ /* the Module containing UserModel */ ]
})
+2ms
Error: Nest can't resolve dependencies of the UsersService (?). Please make sure that the argument UserModel at index [0] is available in the AuthModule context.
It seems that it is due to the following injection in my UsersService :
constructor(#InjectModel('User') private readonly UserModel: Model) {}
but I doesn't know how to solve this problem. My training project is stored on github :
https://github.com/afontange/nest-js.git
I read other tickets on same subject but I don't know what is the solution for my problem.
Thanks for your help.
export const UsersSchema = new Schema({
name: String,
});
Module({
imports: [
MongooseModule.forFeature([{ name: 'Users', schema: UsersSchema }]) // add
],
controllers: [],
providers: [],
exports: []
})
export class AuthModule {}
Do you add in your Auth.module.ts
The AuthModule is the following:
import { Module } from '#nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '#nestjs/passport';
import { LocalStrategy } from './local.strategy';
import { UsersService } from '../users/users.service';
#Module({
imports: [UsersModule, PassportModule],
providers: [AuthService, LocalStrategy, UsersService],
})
export class AuthModule {}

Nest can't resolve dependencies of the ProductModel (?)

I am trying to implement Mongoose crud service. I am missing something on injecting model or injecting module.
I am getting below error:
Nest can't resolve dependencies of the ProductModel (?). Please make sure that the argument DatabaseConnection at index [0] is available in the MongooseModule context
app.module.ts
#Module({
imports: [ProductsModule,
MongooseModule.forRoot(config.mongoURI)],
})
export class AppModule { }
product.module.ts
#Module({
imports: [MongooseModule.forFeature([{ name: 'MyProduct', schema: ProductSchema }])],
controllers: [ProductsController],
providers: [ProductsService],
exports: [ProductsService]
})
export class ProductsModule { }
product.service.ts
#Injectable()
export class ProductsService extends GenericMongooseCrudService<IProduct> {
eventEmitter: EventEmitter = new EventEmitter();
#InjectModel('MyProduct') private readonly userModel: Model<IProductModel>;
}
product.interface.ts
export interface IProduct extends IModelInstance {
value: string
}
export interface IProductModel extends IProduct, IMongoDocument {
}

Resources