I am working with NestJSproject. I make an entity Client and a DTO for the "inscrit()" function
when I ran the project, I got the following:
ERROR [ExceptionHandler] Nest can't resolve dependencies of the ClientService (?). Please make sure that the argument ClientRepository at index [0] is available in the ClientModule context.
Potential solutions:
- If ClientRepository is a provider, is it part of the current ClientModule?
- If ClientRepository is exported from a separate #Module, is that module imported within ClientModule?
#Module({
imports: [ /* the Module containing ClientRepository */ ]
})
this is the client.service.ts file
import { Injectable } from '#nestjs/common';
import { InjectRepository } from '#nestjs/typeorm';
import { Repository } from 'typeorm';
import { ClientInscritDto } from './dto/client-inscrit.dto';
import { Client } from './entity/client.entity';
import * as bcrypt from 'bcrypt';
import { ConflictException } from '#nestjs/common/exceptions';
#Injectable()
export class ClientService {
constructor(
#InjectRepository(Client)
private clientRepository : Repository<Client>
){}
async inscrit(clientData: ClientInscritDto) : Promise<Partial<Client>>{
const client = this.clientRepository.create({...clientData});
client.salt = await bcrypt.genSalt();
client.mdp = await bcrypt.hash(clientData.mdp, client.salt);
try{
await this.clientRepository.save(client);
}catch(err){
throw new ConflictException(`le surname ${clientData.surname} ou l'email ${clientData.email} existe déjà`);
}
return client;
}
}
The answer for this was that I forget adding in client.module.ts file:
imports: [
TypeOrmModule.forFeature([Client])
],
Related
New to NestJS and TypeORM, and the similar questions on SO didn't solve my problem.
I have a custom TypeORM repository in NestJS using it in service, but it fails with error:
TypeError: this.tenantRepository.createTenant is not a function.
tenants.module.ts:
import { TenantRepository } from './tenant.repository';
#Module({
imports: [
TypeOrmModule.forFeature([TenantRepository]),
],
controllers: [TenantsController],
providers: [TenantsService],
})
export class TenantsModule { }
tenant.repository.ts:
// ...
import { TenantEntity } from './entities/tenant.entity';
#EntityRepository(TenantEntity)
export class TenantRepository extends Repository<TenantEntity>{
async createTenant(createTenantDto: CreateTenantDto): Promise<TenantEntity> {
const { name, email } = createTenantDto;
const newTenant = new TenantEntity()
newTenant.name = name;
newTenant.email = email;
await newTenant.save()
return newTenant;
}
}
And here's where the error is triggered (tenants.service.ts)
// ...
import { TenantEntity } from './entities/tenant.entity';
import { TenantRepository } from './tenant.repository';
#Injectable()
export class TenantsService {
constructor(
#InjectRepository(TenantRepository)
private tenantRepository: TenantRepository
) { }
async createTenant(createTenantDto: CreateTenantDto): Promise<TenantEntity> {
return await this.tenantRepository.createTenant(createTenantDto); // <-- ERROR
}
}
I can inject entity in service and use it for simple CRUD, but I want to separate concerns and use the repository pattern.
This is a POST endpoint and the error is only after submission from Swagger.
Also, VS Code autocomplete is suggesting createTenant after typing this.tenantRepository
Where am I going wrong?
EntityRepository decorator was deprecated, and as far as I know, you need to define a custom class that extends Repository and decorate it with #Injectable. Hence, you need to have some changes as follows:
tenant.repository.ts:
import { Injectable } from '#nestjs/common';
import { DataSource, Repository } from 'typeorm';
#Injectable()
export class TenantRepository extends Repository<TenantEntity>{
constructor(private dataSource: DataSource) {
super(TenantEntity, dataSource.createEntityManager());
}
async createTenant(createTenantDto: CreateTenantDto): Promise<TenantEntity> {
const { name, email } = createTenantDto;
const newTenant = this.create({ name, email });
await this.save(newTenant);
return newTenant;
}
}
tenants.module.ts:
import { TenantRepository } from './tenant.repository';
#Module({
imports: [
TypeOrmModule.forFeature([TenantRepository]),
],
controllers: [TenantsController],
providers: [TenantsService, TenantRepository],
})
export class TenantsModule { }
tenants.service.ts:
import { TenantEntity } from './entities/tenant.entity';
import { TenantRepository } from './tenant.repository';
#Injectable()
export class TenantsService {
constructor(
private tenantRepository: TenantRepository
) { }
async createTenant(createTenantDto: CreateTenantDto): Promise<TenantEntity> {
return await this.tenantRepository.createTenant(createTenantDto);
}
}
You also have access to built-in typeorm methods like save, create, find, etc. since the custom repository is derived from Repository class.
by example:
[https://stackoverflow.com/questions/72549668/how-to-do-custom-repository-using-typeorm-mongodb-in-nestjs][1]
Created custom repository в yandex-ndd-api-client.module:
import { DataSource, Repository } from 'typeorm';
import { Injectable } from '#nestjs/common';
// import {Team} from '#Domain/Team/Models/team.entity';
import { TestRepositoryTypeorm } from '../entity/testRepositoryTypeorm.entity';
#Injectable()
export class TestRepository extends Repository<TestRepositoryTypeorm> {
constructor(private dataSource: DataSource) {
super(TestRepositoryTypeorm, dataSource.createEntityManager());
}
async findTest(): Promise<any> { //TestRepositoryTypeorm | undefined
const findTests = await this.dataSource
.getRepository(TestRepositoryTypeorm)
.createQueryBuilder('test')
.getMany();
return await findTests;
}
}
Connected in the module::
providers: [YandexDeliveryService, YandexNddApiClientService, ConfigService, SyncService, TestRepository],
Connected it to the service yandex-ndd-api-client.service:
import { TestRepository } from './repository/testRepositoryTypeorm.retository';
#Injectable()
export class YandexNddApiClientService {
constructor(
// private yandexDeliveryApiService: YandexDeliveryApiService,
private httpService: HttpService,
private dataSource: DataSource,
private configService: ConfigService,
#Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger,
// #InjectRepository(TestRepository)
private testRepository: TestRepository,
) {}
Called in service:
//testRepositoryTypeorm
async testRepositoryTypeorm(): Promise<any> {
try {
console.log('testRepositoryTypeorm');
// return 'testRepositoryTypeorm';
return await this.testRepository.findTest();
} catch (e) {
console.log('ERROR testRepositoryTypeorm:', e);
}
}
As a result:
ERROR [ExceptionHandler] Nest can't resolve dependencies of the YandexNddApiClientService (HttpService, DataSource, ConfigService, winston, ?, SchedulerRegistry). Please make sure that the argument TestRepository at index [4] is available in the DetmirApiClientModule context.
Potential solutions:
- If TestRepository is a provider, is it part of the current DetmirApiClientModule?
- If TestRepository is exported from a separate #Module, is that module imported within DetmirApiClientModule?
#Module({
imports: [ /* the Module containing TestRepository */ ]
})
[1]: https://stackoverflow.com/questions/72549668/how-to-do-custom-repository-using-typeorm-mongodb-in-nestjs
DetmirApiClientModule.ts:
import { Module } from '#nestjs/common';
import { DetmirApiClientService } from './detmir-api-client.service';
import { DetmirApiClientController } from './detmir-api-client.controller';
import { SyncService } from 'src/sync.service';
import { YandexNddApiClientService } from 'src/yandex-ndd-api-client/yandex-ndd-api-client.service';
import { HttpModule, HttpService } from '#nestjs/axios';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { YandexNddApiClientModule } from 'src/yandex-ndd-api-client/yandex-ndd-api-client.module';
#Module({
providers: [DetmirApiClientService, SyncService, YandexNddApiClientService],
controllers: [DetmirApiClientController],
imports: [HttpModule, YandexNddApiClientModule], //TestRepository
})
export class DetmirApiClientModule {}
Most likely your YandexNddApiClientModule does not add the YandexNddApiClientService to the exports array. Add YandexNddApiClientService to the exports if it is not already there and remove YandexNddApiClientService from the providers array of DetmirApiClientModule. The error is being raised because you have YandexNddApiClientService declared in the providers of DetmirApiClientModule so Nest is trying to create the provider in the new module rather than re-use the module from its original context
I get this error:
Nest can't resolve dependencies of the UserPreferencesService (?). Please make sure that the argument UserPreferencesSchemaModel at index [0] is available in the UserPreferencesModule context.
What can the error be? I understand that the problem happens in the user-preferences.service.ts file. as when I comment the following lines from the user-preferences.module.ts file all works fine.
controllers: [UserPreferencesController],
providers: [UserPreferencesService],
This is my user-preferences.service.ts file:
import { Injectable } from '#nestjs/common';
import { Model } from 'mongoose';
import { InjectModel } from '#nestjs/mongoose';
import { UserPreferencesInterface } from './interfaces/user-preferences.interface';
#Injectable()
export class UserPreferencesService {
constructor(
#InjectModel('UserPreferencesSchema')
private readonly UserPreferencesModel: Model<UserPreferencesInterface>,
) {}
public async postUserPreferences(newUserPreferences: any): Promise<any> {
const userPreferences = await new this.UserPreferencesModel(
newUserPreferences,
);
return userPreferences.save();
}
}
app.module.ts
import { Module } from '#nestjs/common';
import { UserPreferencesModule } from './user-preferences/user-preferences.module';
import { MongooseModule } from '#nestjs/mongoose';
#Module({
imports: [
UserPreferencesModule,
MongooseModule.forRoot(
'mongodb+srv://user:pass#db.hucjifz.mongodb.net/dbname?retryWrites=true&w=majority',
),
],
})
export class AppModule {}
user-preferences.module.ts
import { Module } from '#nestjs/common';
import { MongooseModule } from '#nestjs/mongoose';
import { UserPreferencesSchema } from './schemas/user-preferences.schema';
import { UserPreferencesController } from './user-preferences.controller';
import { UserPreferencesService } from './user-preferences.service';
#Module({
imports: [
MongooseModule.forFeature([
{
name: 'UserPreferences',
schema: UserPreferencesSchema,
},
]),
],
controllers: [UserPreferencesController],
providers: [UserPreferencesService],
})
export class UserPreferencesModule {}
user-preferences.controller.ts
import {Body, Controller, Get, Post, Put } from '#nestjs/common';
import { UserPreferencesService } from './user-preferences.service';
import { UserPreferencesDto } from './dto/user-preferences.dto'
#Controller('user-preferences')
export class UserPreferencesController {
constructor(private userPreferencesService: UserPreferencesService) {}
#Get()
public getUserPreferences() {
return this.userPreferencesService.getUserPreferences();
}
#Post ()
public postUserPreferences(
#Body() userPreferences: UserPreferencesDto
) {
return this.userPreferencesService.postUserPreferences( userPreferences );
}
}
this is the complete error:
[Nest] 65481 - 06/07/2022, 6:00:04 AM ERROR [ExceptionHandler] Nest can't resolve dependencies of the UserPreferencesService (?). Please make sure that the argument UserPreferencesSchemaModel at index [0] is available in the UserPreferencesModule context.
Potential solutions:
- If UserPreferencesSchemaModel is a provider, is it part of the current UserPreferencesModule?
- If UserPreferencesSchemaModel is exported from a separate #Module, is that module imported within UserPreferencesModule?
#Module({
imports: [ /* the Module containing UserPreferencesSchemaModel */ ]
})
Error: Nest can't resolve dependencies of the UserPreferencesService (?). Please make sure that the argument UserPreferencesSchemaModel at index [0] is available in the UserPreferencesModule context.
Potential solutions:
- If UserPreferencesSchemaModel is a provider, is it part of the current UserPreferencesModule?
- If UserPreferencesSchemaModel is exported from a separate #Module, is that module imported within UserPreferencesModule?
#Module({
imports: [ /* the Module containing UserPreferencesSchemaModel */ ]
})
at Injector.lookupComponentInParentModules (/Users/davids/Developmet/nestjs/sync-user-preferences/node_modules/#nestjs/core/injector/injector.js:231:19)
at Injector.resolveComponentInstance (/Users/davids/Developmet/nestjs/sync-user-preferences/node_modules/#nestjs/core/injector/injector.js:184:33)
at resolveParam (/Users/davids/Developmet/nestjs/sync-user-preferences/node_modules/#nestjs/core/injector/injector.js:106:38)
at async Promise.all (index 0)
at Injector.resolveConstructorParams (/Users/davids/Developmet/nestjs/sync-user-preferences/node_modules/#nestjs/core/injector/injector.js:121:27)
at Injector.loadInstance (/Users/davids/Developmet/nestjs/sync-user-preferences/node_modules/#nestjs/core/injector/injector.js:52:9)
at Injector.loadProvider (/Users/davids/Developmet/nestjs/sync-user-preferences/node_modules/#nestjs/core/injector/injector.js:74:9)
at async Promise.all (index 3)
at InstanceLoader.createInstancesOfProviders (/Users/davids/Developmet/nestjs/sync-user-preferences/node_modules/#nestjs/core/injector/instance-loader.js:44:9)
at /Users/davids/Developmet/nestjs/sync-user-preferences/node_modules/#nestjs/core/injector/instance-loader.js:29:13
O.K, after digging alot I found that the problem was caused because MongooseModule.forFeature name and #InjectModel() in user-preferences.service.ts value were not identical.
They must be identical.
I am using Axios in my project to call some third-party endpoints. I don't seem to understand the
error
Nest can't resolve dependencies of the HttpService (?). Please make sure that the argument
AXIOS_INSTANCE_TOKEN at index [0] is available in the TimeModule context.
Potential solutions:
- If AXIOS_INSTANCE_TOKEN is a provider, is it part of the current TimeModule?
- If AXIOS_INSTANCE_TOKEN is exported from a separate #Module, is that module imported within TimeModule?
#Module({
imports: [ /* the Module containing AXIOS_INSTANCE_TOKEN */ ]
})
This is the module
#Module({
imports: [TerminalModule,],
providers: [TimeService, HttpService],
controllers: [TimeController]
})
export class TimeModule { }
This is the service
#Injectable()
export class TimeService {
constructor(private httpService: HttpService,
#InjectModel('PayMobileAirtime') private time: Model<Time>,
#Inject(REQUEST) private request: any,
) { }
This is an example of one of my get and post methods
async PrimeAirtimeProductList(telcotime: string) {
let auth = await this.TimeAuth()
const productList = await this.httpService.get(`https://clients.time.com/api/top/info/${telcotime}`,
{
headers: {
'Authorization': `Bearer ${auth.token}`
}
}
).toPromise();
return productList.data
}
Post
const dataToken = await this.manageTimeAuth()
const url = `https://clients.time.com/api/dataup/exec/${number}`
const BuyTelcoData = await this.httpService.post(url, {
"product_id": product_id,
"denomination": amount,
"customer_reference": reference_id
}, {
headers: {
'Authorization': `Bearer ${dataToken.token}`
}
}).toPromise();
const data = BuyTelcoData.data;
Import HttpModule from #nestjs/common in TimeModule and add it to the imports array.
Remove HttpService from the providers array in TimeModule. You can directly import it in the TimeService.
import { HttpModule } from '#nestjs/common';
...
#Module({
imports: [TerminalModule, HttpModule],
providers: [TimeService],
...
})
TimeService:
import { HttpService } from '#nestjs/common';
If your response type is an Observable of type AxiosResponse, then import these two as well in the service file TimeService.
import { Observable } from 'rxjs';
import { AxiosResponse } from 'axios';
For reference, check out http-module and this post.
Don't pass HttpService in the providers. Import only HttpModule.
I'm getting this error when I run my NestJS app.
[Nest] 19139 - 03/01/2020, 2:10:01 PM [ExceptionHandler] Nest can't resolve dependencies of the AccountsService (AccountRepository, ?, HashPasswordService). Please make sure that the argument Object at index [1] is available in the AccountsModule context.
Potential solutions:
- If Object is a provider, is it part of the current AccountsModule?
- If Object is exported from a separate #Module, is that module imported within AccountsModule?
#Module({
imports: [ /* the Module containing Object */ ]
})
+1ms
I am a bit confused what it causing this. As far as I can tell, my code looks correct. Here is the definition for my AccountsService class:
import { Injectable, ConflictException, Logger, InternalServerErrorException, NotFoundException, Inject } from '#nestjs/common';
import { InjectRepository } from '#nestjs/typeorm';
import { Account } from 'src/accounts/entities/account';
import { Repository, FindManyOptions, UpdateDateColumn } from 'typeorm';
import { CreateAccount } from 'src/accounts/dtos/create-account';
import { GetAccountsWithFilters } from 'src/accounts/dtos/get-accounts-with-filters';
import { UpdateAccountProfileInfo } from 'src/accounts/dtos/update-account-profile-info';
import { HashPasswordService } from '../hash-password/hash-password.service';
import { UpdateEmail } from 'src/accounts/dtos/update-email';
import { UpdatePhone } from 'src/accounts/dtos/update-phone';
import { AccountRepository } from 'src/accounts/repositories/account-repository';
/**
* AccountsService encapsulates all the actions that can be performed by an account.
*/
#Injectable()
export class AccountsService {
constructor(
#InjectRepository(AccountRepository) private accountRepository: AccountRepository,
private logger = new Logger("Accounts Service"),
#Inject(HashPasswordService)
private hashPasswordService: HashPasswordService,
) { }
// more code here
}
My Module looks like this.
import { Module } from '#nestjs/common';
import { AccountsService } from './services/accounts/accounts.service';
import { TypeOrmModule } from '#nestjs/typeorm';
import { Account } from './entities/account';
import { AccountsController } from './controllers/accounts/accounts.controller';
import { AccountCleanerService } from './services/account-cleaner/account-cleaner.service';
import { AuthenticationService } from './services/authentication/authentication.service';
import { AuthenticationController } from './controllers/authentication/authentication.controller';
import { HashPasswordService } from './services/hash-password/hash-password.service';
import { JwtModule } from "#nestjs/jwt";
import { PassportModule } from "#nestjs/passport";
import { JwtStrategy } from './auth-strategies/jwt-strategy';
import { AccountRepository } from './repositories/account-repository';
#Module({
imports: [
TypeOrmModule.forFeature([
Account,
AccountRepository,
]),
JwtModule.register({
secret: "SOME_APP_SECRET",
signOptions: {
expiresIn: 3600
}
}),
PassportModule.register({
defaultStrategy: "jwt",
}),
],
controllers: [
AccountsController,
AuthenticationController,
],
providers: [
AccountRepository,
HashPasswordService,
AccountsService,
AccountCleanerService,
AuthenticationService,
JwtStrategy,
],
exports: [JwtStrategy, PassportModule],
})
export class AccountsModule { }
Lastly, here is the App Module:
import { Module } from '#nestjs/common';
import { AccountsModule } from './accounts/accounts.module';
import { TypeOrmModule } from "#nestjs/typeorm";
import {Account} from "./accounts/entities/account";
import { ConfigModule } from "#nestjs/config";
import account from "./../config/account";
import auth from "./../config/auth";
import database from "./../config/database";
import server from "./../config/server";
import { AccountRepository } from './accounts/repositories/account-repository';
#Module({
imports: [
AccountsModule,
ConfigModule.forRoot({
// make this module available globally
isGlobal: true,
// The configuration files.
load: [
account,
auth,
database,
server
],
}),
TypeOrmModule.forRoot({
type: "mongodb",
url: "my connection string here",
entities: []
}),
],
controllers: [],
providers: [],
})
export class AppModule { }
As you can see, I have clearly made the services available to the module. So, I am kind of confused why Nest is unable to resolve the dependencies. Additionally, there should not be any other module right now, aside from the App module.,, which is also provided above. Any ideas why NestJS is throwing this error?
Nest is having trouble resolving the dependency of Logger, and as it is not provided in the providers array, it won't be able to resolve it. You've got three options:
1) Move the private logger = new Logger('Account Service') to the body of the constructor
2) Move the private logger = new Logger('Account Service') to the third position and mark it as #Optional() so that Nest doesn't throw an error when the value is unknown.
3) Add Logger to the providers array of AccountModule and then use the this.logger.setContext() method to properly set the context
The built in Logger class is #Injectable() so it is possible to use it through DI, but you have to ensure that it is provided just as any other provider is in the NestJS ecosystem.