How to fix NestJS #InjectModel() dependency error? - javascript

rememberLink.scheme.ts
import { Prop, Schema, SchemaFactory } from '#nestjs/mongoose';
import { Document, Types } from 'mongoose';
import { User } from 'src/users/schemas/users.schema';
export type RememberLinkDocument = RememberLink & Document;
#Schema({versionKey: false, timestamps: true})
export class RememberLink {
#Prop({ type: String, required: true })
code: string;
#Prop({ type: Types.ObjectId, ref: User.name, required: true })
user: User;
}
export const RememberLinkSchema = SchemaFactory.createForClass(RememberLink);
remember-password.module.ts
import { Module } from '#nestjs/common';
import { MongooseModule } from '#nestjs/mongoose';
import { RememberPasswordController } from './remember-password.controller';
import { RememberPasswordService } from './remember-password.service';
import { RememberLink, RememberLinkSchema } from './schemas/rememberLink.schema';
#Module({
imports: [
MongooseModule.forFeature([{
name: RememberLink.name,
schema: RememberLinkSchema
}])
],
controllers: [RememberPasswordController],
providers: [RememberPasswordService],
exports: [RememberPasswordService]
})
export class RememberPasswordModule {}
remember-password.service.ts
import { Injectable } from '#nestjs/common';
import { InjectModel } from '#nestjs/mongoose';
import { Model } from 'mongoose';
import { UserDto } from 'src/users/dto/user.dto';
import { User } from 'src/users/schemas/users.schema';
import { RememberLinkDto } from './dto/rememberLink.dto';
import { RememberLink, RememberLinkDocument } from './schemas/rememberLink.schema';
#Injectable()
export class RememberPasswordService {
constructor( #InjectModel(RememberLink.name) private readonly rememberLinkModel: Model<RememberLinkDocument> ) {}
async getUserByRememberCode(code: string): Promise<UserDto> {
return await this.rememberLinkModel.findOne({code}).populate(User.name).lean();
}
}
Error:
Nest can't resolve dependencies of the RememberPasswordService (?).
Please make sure that the argument RememberLinkModel at index [0] is
available in the RememberPasswordService context.

What I would do is export the MongooseModule as well, Its just that the dependency injection knows that there will be Separate module for that model somewhere in the App
#Module({
imports: [
MongooseModule.forFeature([{
name: RememberLink.name,
schema: RememberLinkSchema
}])
],
controllers: [RememberPasswordController],
providers: [RememberPasswordService],
exports: [MongooseModule,RememberPasswordService] // <-- MongooseModule added here
})
export class RememberPasswordModule {}

Fixed. It was import "RememberPasswordService" instead of "RememberPasswordModule" in another module

Related

Everything is imported but Nest can't resolve dependencies of the stripePaymentService

I am integrating Stripe payment gateway through NestJS. I am getting the error which says "Nest can't resolve dependencies of the stripePaymentService". Although I am quite familiar with this error but somehow things are not working for me. I believe everything is imported where it should be.
This is complete error:
Error: Nest can't resolve dependencies of the stripePaymentService (?). Please make sure that the argument paymentIntentRepository at index [0] is available in the AppModule context.
Potential solutions:
- Is AppModule a valid NestJS module?
- If paymentIntentRepository is a provider, is it part of the current AppModule?
- If paymentIntentRepository is exported from a separate #Module, is that module imported within AppModule?
My stripePaymentModule is
/* eslint-disable prettier/prettier */
import { Module } from '#nestjs/common';
import { stripePaymentController } from './stripe-payment.controller';
import { stripePaymentService } from './stripe-payment.service';
import { TypeOrmModule } from '#nestjs/typeorm';
import { paymentIntent } from './entities/paymentIntent.entity';
import { ConfigModule } from '#nestjs/config';
#Module({
imports:[
ConfigModule.forRoot({
isGlobal: true,
}),
TypeOrmModule.forFeature([paymentIntent])],
controllers: [stripePaymentController],
providers: [stripePaymentService],
exports: [stripePaymentService],
})
export class stripePaymentModule {}
stripePaymentServices is
/* eslint-disable prettier/prettier */
import { Injectable, Logger } from '#nestjs/common';
import { InjectStripe } from 'nestjs-stripe';
import { ConfigService } from '#nestjs/config';
import Stripe from 'stripe';
import { paymentIntent } from './entities/paymentIntent.entity';
import { InjectRepository } from '#nestjs/typeorm';
import { Repository } from 'typeorm';
#Injectable()
export class stripePaymentService {
stripe: Stripe;
logger = new Logger(stripePaymentService.name);
constructor(
#InjectRepository(paymentIntent)
private readonly paymentIntent:Repository<paymentIntent>,
)
{const stripeApiKey = process.env.STRIPE_SECRET_KEY;
this.stripe = new Stripe(stripeApiKey, {
apiVersion: '2022-11-15',
});}
async payment_intent(data: any, user) {
const intent = await this.stripe.paymentIntents.create({
amount: data.amount,
currency: data.currency,
description: data.description,
payment_method_types: ['card'],
});
return await this.paymentIntent.save({'userId':user.userId, 'intent_response':JSON.stringify(intent)})
// return intent;
}
}
And finally this is app.module
/* eslint-disable prettier/prettier */
import { Module } from '#nestjs/common';
import { UsersModule } from './users/users.module';
import { ConfigModule, ConfigService } from '#nestjs/config';
import { TypeOrmModule } from '#nestjs/typeorm';
import { AuthModule } from './auth/auth.module';
import { User } from './users/entities/user.entity';
import { PassportModule } from '#nestjs/passport';
import { MailModule } from './mail/mail.module';
import { FlightBookingModule } from './flight-booking/flight-booking.module';
import { TravelBookings } from './flight-booking/entities/bookingToken.entity';
import { stripePaymentService } from './stripe/stripe-payment.service';
import { stripePaymentController } from './stripe/stripe-payment.controller';
import { StripeModule } from 'nestjs-stripe';
import { stripePaymentModule } from './stripe/stripe-payment.module';
import { paymentIntent } from './stripe/entities/paymentIntent.entity';
#Module({
imports: [
ConfigModule.forRoot({ isGlobal: true }),
StripeModule.forRoot({
apiKey: process.env.STRIPE_API_KEY,
apiVersion: '2022-11-15'
}),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
useFactory: (configService: ConfigService) => ({
type: 'postgres',
host: configService.get('DB_HOST'),
port: +configService.get<number>('DB_PORT'),
username: configService.get('DB_USERNAME'),
password: configService.get('DB_PASSWORD'),
database: configService.get('DB_NAME'),
entities: [User, TravelBookings, paymentIntent],
synchronize: true,
}),
inject: [ConfigService],
}),
PassportModule,
UsersModule,
AuthModule,
MailModule,
FlightBookingModule,
stripePaymentModule
],
controllers: [stripePaymentController],
providers: [stripePaymentService],
})
export class AppModule {}
The error is thrown from AppModule context. You wouldn't need to put stripePaymentService as a provider in AppModule.
If stripePaymentService is used by other modules, once you have export it, you just need to import the related module in a module that you want, and that would be enough.
So all you need to do is remove these lines from AppModule:
providers: [stripePaymentService]
You can remove this line as well:
controllers: [stripePaymentController]

Unable to add auth0 authentication to a graphql based nestjs app

I want to add authentication to my graphql app in nestjs. the token I receive is from auth0.
Im fairly new to nestjs I have looked at its documentation. this is the best I could comeup with and it still isnt working
this is my code where Im trying to add auth
app.module
import { Module } from '#nestjs/common';
import { ConfigModule } from '#nestjs/config';
import { MongooseModule } from '#nestjs/mongoose';
import { databaseConfig, applicationConfig } from '../../config/';
import MongoServiceClass from '../../services/Mongo';
import { ConfigModule as AppConfigModule } from '../config/config.module';
import { GraphQLModule } from '#nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '#nestjs/apollo';
import { LoggingPlugin } from 'src/plugins/LoggerCustom';
import { UserModule } from './user/user.module';
import { QuotaModule } from './quota/quota.module';
import { QuotaManagementModule } from './quota-management/quota-management.module';
import { BobModule } from './bob/bob.module';
import { SlModule } from './sl/sl.module';
import { SlQModule } from './sl-q/sl-q.module';
import { AuthModule } from '../auth/auth.module';
const NODE_ENV = process.env.NODE_ENV;
#Module({
imports: [
LoggingPlugin,
ConfigModule.forRoot({
load: [applicationConfig, databaseConfig],
envFilePath: `.env.${NODE_ENV}`,
isGlobal: true,
}),
MongooseModule.forRootAsync({
useClass: MongoServiceClass,
}),
AuthModule,
GraphQLModule.forRoot<ApolloDriverConfig>({
autoSchemaFile: 'schema.gql',
driver: ApolloDriver,
path: '/graphql',
playground: true,
debug: true,
}),
BobModule,
QuotaModule,
QuotaManagementModule,
AppConfigModule,
SlQModule,
SlModule,
UserModule,
],
})
export class AppModule {}
auth.module
import { Global, Module } from '#nestjs/common';
import { UserModule } from '../app/user/user.module';
import { AuthService } from './auth.service';
import { AuthResolver } from './auth.resolver';
import { GqlAuth0Guard } from './gql.guard';
import { GqlAuth0JwtStrategy } from './gql-auth0-jwt.strategy';
import { PassportModule } from '#nestjs/passport';
#Global()
#Module({
imports: [UserModule, PassportModule.register({ defaultStrategy: 'jwt' })],
providers: [AuthService, AuthResolver, GqlAuth0JwtStrategy, GqlAuth0Guard],
})
export class AuthModule {}
gql-auth0-jwt.strategy
import { Injectable, UnauthorizedException } from '#nestjs/common';
import { PassportStrategy } from '#nestjs/passport';
import { Strategy as BaseStrategy, ExtractJwt, VerifiedCallback } from 'passport-jwt';
import { passportJwtSecret } from 'jwks-rsa';
#Injectable()
export class GqlAuth0JwtStrategy extends PassportStrategy(BaseStrategy) {
domain = 'https://dev-ab454a.us.auth0.com/';
constructor() {
super({
secretOrKeyProvider: passportJwtSecret({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 5,
jwksUri: `https://dev-ab454a.us.auth0.com/.well-known/jwks.json`,
}),
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
audience: 'https://hyyype-app.herokuapp.com/',
issuer: 'https://dev-ab454a.us.auth0.com/',
});
}
validate(payload: any, done: VerifiedCallback) {
console.log('Validate JWT-STRATEGY');
if (!payload) {
done(new UnauthorizedException(), false);
}
return done(null, payload);
}
}
gql.guard
import { ExecutionContext, Injectable } from '#nestjs/common';
import { GqlExecutionContext } from '#nestjs/graphql';
import { AuthGuard } from '#nestjs/passport';
#Injectable()
export class GqlAuth0Guard extends AuthGuard('jwt') {
getRequest(context: ExecutionContext) {
console.log('GQL-AUTH0-GUARD');
const ctx = GqlExecutionContext.create(context);
return ctx.getContext().req;
}
}
auth.resolver
import { UnauthorizedException, UseGuards } from '#nestjs/common';
import { Query, Resolver } from '#nestjs/graphql';
import { CurrentUser } from './auth.decorator';
import { GqlAuth0Guard } from './gql.guard';
#Resolver()
export class AuthResolver {
#Query(() => String)
#UseGuards(GqlAuth0Guard)
getAuthenticatedUser(#CurrentUser() user: any) {
if (!user) {
throw new UnauthorizedException('Get Auth User');
}
return user;
}
}
this is my response after i send a request I have checked the token is valid
GQL-AUTH0-GUARD
error: 586ms - Unauthorized

Nest can't resolve dependencies of the service?

I'm trying access a database using a custom provider as per this guide. At startup, Nestjs throws the error Nest can't resolve dependencies of the EventsService (?). Please make sure that the argument DATA_SOURCE at index [0] is available in the AppModule context.
Here are my files
Database providers
import { DataSource } from 'typeorm';
export const databaseProviders = [
{
provide: 'DATA_SOURCE',
useFactory: async () => {
const dataSource = new DataSource({
type: "mysql",
host: "host",
port: 3306,
username: "username",
password: "password",
synchronize: true,
logging: true,
});
return dataSource.initialize();
},
},
];
Database module
import { databaseProviders } from "./database.providers";
import { Module } from "#nestjs/common";
#Module({
providers: [...databaseProviders],
exports: [...databaseProviders],
})
export class DatabaseModule {}
Events service
import { Inject, Injectable } from '#nestjs/common';
import { DataSource } from 'typeorm';
import { DatabaseModule } from './database.module';
import { Event } from './entities/event.entity';
import { EventInvite } from './entities/eventInvite.entity';
#Injectable()
export class EventsService {
constructor(#Inject("DATA_SOURCE") private readonly database: DataSource) { }
createEvent(userId: string, event: Event) {
this.database.manager.create(Event, event)
}
deleteEvent(eventId: string){
this.database.manager.delete(Event, { eventId })
}
}
Events Module
import { Module } from '#nestjs/common';
import { DatabaseModule } from './database.module';
import { EventsController } from './events.controller';
import { EventsService } from './events.service';
#Module({
imports: [DatabaseModule],
controllers: [EventsController],
providers: [EventsService],
exports: [EventsService]
})
export class EventsModule {}
App module
import { Module } from '#nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { EventsController } from './events/events.controller';
import { EventsService } from './events/events.service';
import { EventsModule } from './events/events.module';
import { DatabaseModule } from './events/database.module';
#Module({
imports: [],
controllers: [AppController, EventsController],
providers: [AppService, EventsService],
})
export class AppModule {}
If I import DatabaseModule inside of AppModule everything works. My question is, why is this required? My understanding thus far is that Nestjs builds a dependency tree, which in this case should look something like AppModule => EventService => DatabaseService. AppModule doesn't directly access DatabaseService, and therefore shouldn't need to import it directly, so why is Nestjs failing to resolve this dependency?
that module isn't global, thus its providers aren't globally available. As you're registering the service EventsService again in AppModule, you need to import the DatabaseModule
I believe this is what you're trying to do (which is pretty much what the docs shows):
#Module({
imports: [EventsModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
than you won't have 2 instances of EventsService and EventsController anymore, only the one registered in EventsModule module.

Nest js: Nest can't resolve dependencies of the Season3Service

I have the following error in nest. I've read the doc but I still don't understand what's going on. This is the full error: "[Nest] 9420 - 21/02/2022, 12:39:24 p. m. ERROR [ExceptionHandler] Nest can't resolve dependencies of the Season3Service (?). Please make sure that
the argument gModel at index [0] is available in the AppModule context". Here is my code:
app.controller.ts:
import { Controller, Get } from '#nestjs/common';
import { ClientRequest } from 'http';
import { AppService } from './app.service';
#Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
#Get()
getHello(): string {
return 'Sarani Mukoe! En el Arco de la Villa del Herrero';
}
}
app.module.ts:
import { Module } from '#nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { Season3Controller } from './season3/season3.controller';
import { Season3Service } from './season3/season3.service';
import { Season3Module } from './season3/season3.module';
import { MongooseModule } from '#nestjs/mongoose';
#Module({
imports: [Season3Module, MongooseModule.forRoot('mongodb://127.0.0.1:27017/DemonSlayer')],
controllers: [AppController, Season3Controller],
providers: [AppService, Season3Service],
})
export class AppModule {}
app.service:
import { Injectable } from '#nestjs/common';
#Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
Then, I have the season3 module folder:
season3.controller.ts:
import { Controller, Get, Post, Put, Delete, Body, Param } from '#nestjs/common';
import { CreateSeasonDto } from './dto/create-season.dto';
import { Season } from './interfaces/Season';
import { Season3Service } from "./season3.service";
#Controller('season3')
export class Season3Controller {
constructor(private season3: Season3Service) {}
#Get()
getSeasons(): Promise<Season[]> {
return this.season3.getSeasons();
}
#Get(':p')
getSeason(#Param('p') id: string): Promise<Season>{
console.log(id);
return this.season3.getSeason(id);
}
#Post()
createSeason(#Body() season: CreateSeasonDto): string {
console.log(
`Título: ${season.titulo}. Cuerpo: ${season.cuerpo}. Realizado: ${season.realizado}`
);
return 'Insertando.... Hinokami Kagura';
}
#Put(':p1')
updateSeason(#Body() cuerpo: CreateSeasonDto, #Param('p1') id): string {
console.log(cuerpo);
console.log(id);
return `Actualizando.... Velocidad Extrema`;
}
#Delete(':id')
deleteSeason(#Param('id') id): string {
console.log(id);
return `Eliminando(${id}) .... Colmillos Afilados`;
}
}
season3.module.ts:
import { Module } from '#nestjs/common';
import { MongooseModule } from '#nestjs/mongoose';
import { Season3Controller } from './season3.controller';
import { Season3Service } from './season3.service';
import { SeasonSchema} from "./schemas/season.schema";
#Module({
imports: [MongooseModule.forFeature([
{name:'g', schema:SeasonSchema}
])],
controllers: [Season3Controller],
providers: [Season3Service],
})
export class Season3Module {}
season3.service.ts:
import { Model } from "mongoose";
import { Injectable } from '#nestjs/common';
import { InjectModel } from '#nestjs/mongoose';
import { Season } from "./interfaces/Season";
#Injectable()
export class Season3Service {
constructor(#InjectModel('g') private seasonModel: Model<Season>) {}
async getSeasons() {
return await this.seasonModel.find();
}
async getSeason(id: string) {
return await this.seasonModel.findById(id);
}
}
It looks like Season3Service is not exported so you won't be able to use it in other modules.
in season3.module.ts add export
import { Module } from '#nestjs/common';
import { MongooseModule } from '#nestjs/mongoose';
import { Season3Controller } from './season3.controller';
import { Season3Service } from './season3.service';
import { SeasonSchema} from "./schemas/season.schema";
#Module({
imports: [MongooseModule.forFeature([
{name:'g', schema:SeasonSchema}
])],
controllers: [Season3Controller],
providers: [Season3Service],
exports: [Season3Service], // <----- make Season3Service public
})
export class Season3Module {}
doc: https://docs.nestjs.com/modules#shared-modules
After this, any other module that imports Season3Module will be able to inject (user) Season3Service
in app.module.ts
import { Module } from '#nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { Season3Controller } from './season3/season3.controller';
import { Season3Module } from './season3/season3.module';
import { MongooseModule } from '#nestjs/mongoose';
#Module({
imports: [Season3Module, MongooseModule.forRoot('mongodb://127.0.0.1:27017/DemonSlayer')],
controllers: [AppController, Season3Controller],
providers: [AppService], // <---- remove Season3Service from providers
})
export class AppModule {}
Now any providers/controllers in AppModule will have access to Season3Service

NestJS Nest can't resolve dependencies of the RolesService (+, +, ?)

Hi I'm programming using the NestJS framework (with MongoDB) and have build some modules now. When I try to import a model from another module it returns this error:
Nest can't resolve dependencies of the RolesService (+, +, ?).
Now, I've implemented the code like this:
app.module.ts
import { GroupsModule } from './groups/groups.module';
import { Module } from '#nestjs/common';
import { MongooseModule } from '#nestjs/mongoose';
import { UsersModule } from 'users/users.module';
import { RolesModule } from 'roles/roles.module';
#Module({
imports: [
MongooseModule.forRoot('mongodb://localhost:27017/example'),
UsersModule,
GroupsModule,
RolesModule,
],
providers: [],
})
export class AppModule {}
users.module.ts
import { Module } from '#nestjs/common';
import { MongooseModule } from '#nestjs/mongoose';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
import { RolesService } from 'roles/roles.service';
import { UserSchema } from './schemas/user.schema';
import { RoleSchema } from 'roles/schemas/role.schema';
#Module({
imports: [
MongooseModule.forFeature([{ name: 'User', schema: UserSchema }]),
MongooseModule.forFeature([{ name: 'Role', schema: RoleSchema }]),
],
controllers: [UsersController],
providers: [UsersService, RolesService],
exports: [UsersService],
})
export class UsersModule {}
users.service.ts
import { Model } from 'mongoose';
import { ObjectID } from 'mongodb';
import { InjectModel } from '#nestjs/mongoose';
import { Injectable, HttpException, HttpStatus } from '#nestjs/common';
import { User } from './interfaces/user.interface';
#Injectable()
export class UsersService {
constructor(#InjectModel('User') private readonly userModel: Model<User>) {}
}
groups.module.ts
import { MongooseModule } from '#nestjs/mongoose';
import { GroupsController } from './groups.controller';
import { RolesService } from '../roles/roles.service';
import { GroupsService } from './groups.service';
import { GroupSchema } from './schemas/group.schema';
import { UserSchema } from '../users/schemas/user.schema';
import { RoleSchema } from '../roles/schemas/role.schema';
#Module({
imports: [
MongooseModule.forFeature([{ name: 'Group', schema: GroupSchema }]),
MongooseModule.forFeature([{ name: 'User', schema: UserSchema }]),
MongooseModule.forFeature([{ name: 'Role', schema: RoleSchema }]),
],
controllers: [GroupsController],
providers: [GroupsService, RolesService],
exports: [GroupsService],
})
groups.service.ts
import { Injectable, HttpException, HttpStatus } from '#nestjs/common';
import { InjectModel } from '#nestjs/mongoose';
import { ObjectID } from 'mongodb';
import { Model } from 'mongoose';
import { Group } from './interfaces/group.interface';
import { User } from '../users/interfaces/user.interface';
import { CreateGroupDto } from './dto/create-group.dto';
import { RolesDto } from 'roles/dto/roles.dto';
import { Role } from '../roles/interfaces/role.interface';
#Injectable()
export class GroupsService {
constructor(#InjectModel('Group') private readonly groupModel: Model<Group>,
#InjectModel('Role') private readonly roleModel: Model<Role>) {} }
roles.module.ts
import { Module } from '#nestjs/common';
import { MongooseModule } from '#nestjs/mongoose';
import { RolesController } from './roles.controller';
import { RolesService } from './roles.service';
import { RoleSchema } from './schemas/role.schema';
import { UserSchema } from '../users/schemas/user.schema';
import { GroupSchema } from '../groups/schemas/group.schema';
#Module({
imports: [
MongooseModule.forFeature([{ name: 'User', schema: UserSchema }]),
MongooseModule.forFeature([{ name: 'Role', schema: RoleSchema }]),
MongooseModule.forFeature([{ name: 'Group', schema: GroupSchema }]),
],
controllers: [RolesController],
providers: [RolesService],
exports: [RolesService],
})
export class RolesModule {}
roles.service.ts
import { Injectable, HttpException, HttpStatus } from '#nestjs/common';
import { InjectModel } from '#nestjs/mongoose';
import { ObjectID } from 'mongodb';
import { Model } from 'mongoose';
import { Role } from './interfaces/role.interface';
import { User } from '../users/interfaces/user.interface';
import { Group } from '../groups/interfaces/group.interface';
import { CreateRoleDto } from './dto/create-role.dto';
import { RolesDto } from './dto/roles.dto';
#Injectable()
export class RolesService {
constructor( #InjectModel('Role') private readonly roleModel: Model<Role>,
#InjectModel('User') private readonly userModel: Model<User>,
#InjectModel('Group') private readonly groupModel: Model<Group> ) {} }
While the DI in the users and roles works fine, the error arise when I try to import the Group Model in the roles service. Please tell me if you see anything wrong, I've follow the same schema from users with groups but unfortunately can't see where the error lives.
Thanks in advance.
UPDATE: OK I think my error is when I try to use a module service function outside the module. I mean I modified (in order to simplify) I'll modify the code this way:
users.module.ts
#Module({
imports: [
MongooseModule.forFeature([{ name: 'User', schema: UserSchema }]),
RolesModule,
],
controllers: [UsersController],
providers: [UsersService, RolesService],
exports: [UsersService],
})
export class UsersModule {}
users.controller.ts
export class UsersController {
constructor(private readonly usersService: UsersService,
private readonly rolesService: RolesService){}
async addRoles(#Param('id') id: string, #Body() userRolesDto: UserRolesDto): Promise<User> {
try {
return this.rolesService.setRoles(id, userRolesDto);
} catch (e){
const message = e.message.message;
if ( e.message.error === 'NOT_FOUND'){
throw new NotFoundException(message);
} else if ( e.message.error === 'ID_NOT_VALID'){
throw new BadRequestException(message);
}
}
}
}
roles.module.ts
#Module({
imports: [
MongooseModule.forFeature([{ name: 'Role', schema: RoleSchema }]),
],
controllers: [RolesController],
providers: [RolesService],
exports: [RolesService],
})
export class RolesModule {}
roles.service.ts
#Injectable()
export class RolesService {
userModel: any;
constructor( #InjectModel('Role') private readonly roleModel: Model<Role> ) {}
// SET USER ROLES
async setRoles(id: string, rolesDto: RolesDto): Promise<User> {
if ( !ObjectID.isValid(id) ){
throw new HttpException({error: 'ID_NOT_VALID', message: `ID ${id} is not valid`, status: HttpStatus.BAD_REQUEST}, 400);
}
try {
const date = moment().valueOf();
const resp = await this.userModel.updateOne({
_id: id,
}, {
$set: {
updated_at: date,
roles: rolesDto.roles,
},
});
if ( resp.nModified === 0 ){
throw new HttpException({ error: 'NOT_FOUND', message: `ID ${id} not found or entity not modified`, status: HttpStatus.NOT_FOUND}, 404);
} else {
let user = await this.userModel.findOne({ _id: id });
user = _.pick(user, ['_id', 'email', 'roles', 'created_at', 'updated_at']);
return user;
}
} catch (e) {
if ( e.message.error === 'NOT_FOUND' ){
throw new HttpException({ error: 'NOT_FOUND', message: `ID ${id} not found or entity not modified`, status: HttpStatus.NOT_FOUND}, 404);
} else {
throw new HttpException({error: 'ID_NOT_VALID', message: `ID ${id} is not valid`, status: HttpStatus.BAD_REQUEST}, 400);
}
}
}
That's it, as you can see when I try to use from users.controller the roles.service setRole method it returns me an error:
Nest can't resolve dependencies of the RolesService (?). Please make sure that the argument at index [0]is available in the current context.
I don't understand where the problem is because I'm injecting the Role model in the roles.module already and it don't understand it. In fact if I don't create the call from users.module to this dependency everything goes fine.
Any tip?
(I've red the suggestion from stackoverflow, I'll don't do it again)
I think the problem is that you're importing the same model multiple times, like:
MongooseModule.forFeature([{ name: 'User', schema: UserSchema }]
and also providing the same service multiple times:
providers: [RolesService]
I would not inject the models themselves but rather the corresponding services that encapsulate the model. Then you export the service in its module and import the module where needed. So the RolesService would inject the UsersSerivce instead of the UserModel.
With your current setup, you would run into circular dependencies though. This can be handled with fowardRef(() => UserService) but should be avoided if possible, see the circular dependency docs. If this is avoidable depends on your business logic however.
If you don't have circular dependencies then for example export your RolesService
#Module({
imports: [MongooseModule.forFeature([{ name: 'Role', schema: RoleSchema }])]
controllers: [RolesController],
providers: [RolesService],
exports: [RolesService],
})
export class RolesModule {}
and import the RolesModule wherever you want to use the RolesService, e.g.:
#Module({
imports: [
RolesModule,
MongooseModule.forFeature([{ name: 'User', schema: UserSchema }])
],
controllers: [UsersController],
providers: [UsersService],
exports: [UsersService],
})

Categories

Resources