Nest can't resolve dependencies of the MailService (MailerService, ?, CreateSendMailDto). Please make sure that the argument EmailRepository at index [1] is available in the MailModule context.
Potential solutions:
- If EmailRepository is a provider, is it part of the current MailModule?
- If EmailRepository is exported from a separate #Module, is that module imported within MailModule?
#Module({
imports: [ /* the Module containing EmailRepository */ ]
})
Error: Nest can't resolve dependencies of the MailService (MailerService, ?, CreateSendMailDto). Please make sure that the argument EmailRepository at index [1] is available in the MailModule context.
Potential solutions:
- If EmailRepository is a provider, is it part of the current MailModule?
- If EmailRepository is exported from a separate #Module, is that module imported within MailModule?
#Module({
imports: [ /* the Module containing EmailRepository */ ]
})
I'm new to nestjs thou not too experienced with nodejs. Pls i need someone to help me understand the context of module export and providers. I don't really know what to export, import, provied or put in controller, i understand some few stuff but i seek full undersanding of how and what is really happening there. Thanks
You didn't add the code producing the error, but I'll try to explain it in simple terms, assuming the following scenario:
You have two resources, Vehicle & Driver, and you want to use DriverService in VehicleService.
Solution:
Export DriverService from driver.module.ts
Then import DriverModule in vehicle.module.ts
#Module({
controllers: [DriverController],
providers: [DriverService],
exports: [DriverService]
})
#Module({
imports:[DriverModule]
controllers: [VehicleController],
providers: [VehicleService],
})
You can visit the NestJs docs for more info.
Related
I'm trying to solve another "Nest can't resolve dependencies" error, which you can find many examples of. I eventually added a #Inject(Type) decorator to the constructor parameter, which solved the issue. Nothing else changed. I would still like to understand why this worked/was necessary.
My first approach followed the examples very closely:
#Controller('consumer')
export class ConsumerController {
constructor(private service: ConsumerService) {}
}
The result was that the application started successfully, but I could see the dependency wasn't satisfied because I could tell from runtime errors that the property was undefined.
Next, I added an explicit #Inject() like:
#Controller('consumer')
export class ConsumerController {
constructor(#Inject() private service: ConsumerService) {}
}
This resulted in errors like Error: Nest can't resolve dependencies of the ConsumerController (?). Please make sure that the argument dependency at index [0] is available in the ConsumerModule context.
There are many example of people asking similar questions and I went through them exhaustively. None of the root causes were applicable in my case.
I thought of trying a custom provider just to help debug the issue, which is when I realized that it's possible to pass the Class of the dependency as an argument to #Inject(). This led to the working version:
#Controller('consumer')
export class ConsumerController {
constructor(#Inject(ConsumerService) private service: ConsumerService) {
}
}
Note that nothing about the module or provider changed between these attempts. I thought that maybe there was a build artifact confusing things so I tried rm -rf lib tsconfig.tsbuildinfo and the behavior was the same.
I would really like to understand why Nest can't satisfy the dependency without the explicit type-key (maybe some tsconfig.json setting)?
Edit: Including module for reference:
#Module({
controllers: [ConsumerController],
providers: [ConsumerService],
})
export class ConsumerModule {}
I'm trying to use the 'mongoose-audit-trail' plugin in nestjs, but I'm getting the following error "Operation 'histories.findOne()' buffering timed out after 10000ms"
export const s = SchemaFactory.createForClass(Product);
s.plugin(require('mongoose-audit-trail').plugin);
Apparently there seems to be something in the connection that you couldn't use!
Or if anyone has any tips on another plugin for #nest to generate change histories I'd appreciate it!
I have recently been working on something similar. I had a problem where I couldn't get existing audit plugins working with nestjs and some of the stuff I have been working on.
I forked an existing library, and my plan is to merge it back and contribute to the original project. However, work has been crazy so not had a chance to finish it.
Maybe this can help you, if you take a look at my recent commits you'll see the modifications I have made.
https://github.com/piercy/mongoose-history-trace/tree/feat/saas
usage wise, you should just be able to use it as a plugin, passing in a few options. From what I can tell, it does work, and does everything you might need for a nestjs, mongoose audit trail.... but it should be noted that while I am working on this, I haven't really tested or put it into a production environment yet.
You are welcome to use this or even finish it off if you want. Sorry I couldn't just give you a plugin to use but hopefully this helps get you in the right direction.
Original Library is here: https://github.com/WelingtonMonteiro/mongoose-history-trace
When you connect to db with MongooseModule.forRoot() or MongooseModule.forRootAsync() It's not the same as mongoose.connect()...
Your plugin tries to get connection from mongoose, but there is not opened one...
So I've Got Solution for this plugin: create mongoose.connection from module like this:
import { Module } from '#nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './services/app.service';
import { MongooseModule } from '#nestjs/mongoose';
import { ConfigService } from './services/config/config.service';
import * as mongoose from 'mongoose';
#Module({
imports: [
MongooseModule.forRootAsync({
imports: [LargeFamilyModule],
useFactory: async (configService: ConfigService) => {
mongoose.set('strictQuery', false);
mongoose.connect(configService.db.uri)
return configService.db
},
inject: [ConfigService],
},),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
It's not a good idea to create to identical db connections, but for this issue it works.
Taking configuration as an example, the Nest.js documentation advocates registering Config Modules and injecting them into other modules in a dependency injection way.
The benefits are obvious, and the dependencies and code are clear, but what if I have a nest.js project that needs to invoke the configuration information at startup? This actually caused me trouble.
My idea is to use a store (actually a closure) to manage all the variables that might be needed globally, the client-side link objects, registered at startup, and introduced when needed.
When corresponding variables are registered in this way, they can be introduced anywhere. The drawback is that you need to manage dependencies yourself.
With the above concept design of demo: https://github.com/sophons-space/nest-server.
Please e help me correct, I am still a rookie.
If you want to use Nest flow it should be defined in the configuration file
// app.module.ts
import configuration from './config/configuration';
imports: [
// first import as first initialization
ConfigModule.forRoot({
isGlobal: true, // to get access to it in every component
load: [configuration],
}),
]
...
// configuration.ts
export default (): any => {
return {
someGlobalConfigVariable: parseInt(process.env.PORT, 10) || 3000,
};
};
Create a file global.service.ts (inside a folder you can name it utils or whatever) & put the code bellow
export class GlobalService{
static globalVar: any;
}
Set value to the globalVar
GlobalService.globalVar = 'some value';
Get value from globalVar
console.log(GlobalService.globalVar);
N.B. Don't forget to import GlobalService wherever you want to use.
The way you can approach this is similar to how NestJS libraries or integrations usually handle configuration; using a method on the base module.
main.ts
import { NestFactory } from '#nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
// Note the `configure`-method
const app = await NestFactory.create(AppModule.configure({
myConfig: 'value',
});
await app.listen(3000);
}
bootstrap();
app.module.ts
import { DynamicModule } from '#nestjs/common';
export class AppModule {
static configure(config): DynamicModule {
return {
module: AppModule,
providers: [{ provide: 'CONFIG', useValue: config }],
// ....
}
}
}
You can use the general NodeJS approach
global.SomeGlobalVariableName = 'SomeGlobalVariableValue';
console.log(SomeGlobalVariableName);
Approach I used is using my config variables in yaml files and then getting those variables or objects wherever I want in my Nestjs project using config package. e.g in default.yml file
key: value
and then in file where I want to use this
import config from 'config';
let value = config.get<string>('key');
you can take this pkg from this npmjs link here
Why not go with more NestJs way i.e. with provide instance scope?
Most of the answers posted here are correct and easy to implement but I have a more generic way to define that variable that fits well in NestJs (Nestjs Scope and Dependency Injection flow). I would be happy to share the sample code, if required
Steps
Create a provider
Add a private instance variable to this provider - instead of a class variable (i.e. static variables) use an instance variable as NestJs automatically (by default) manages the instance of its providers in a singleton way i.e. a single instance of the provider is shared across the entire application. Read more about scopes here
Add get/set and other methods for that variable
Inject that provider wherever you need the global variable (instance variable of the provider(per instance).
Other ways of doing it
Config - preferrable for pre-defined types(like string, number...)
Static variable in util.ts file
Native Global variable - I would not recommend this(explanation is outside the scope of the question)
Recently I wrote for myself a demo-app (full code: https://github.com/aversilov/parley-fork) based on this Ahamed Foysal's example (https://www.codementor.io/foysalit/rest-api-with-mongodb-and-nest-js-hto6x5120). As you know NestJS is a very young framework and there are catastrophicaly small number of tutorials & demo-apps for learn it.
So, I create all files in the project, run mongod in separate terminal window, and run app:
npm run start
But the app is crashed with:
Error output
P.S. I checked - circular references in my codebase don't exists (Vue + typescript - TypeError: Object prototype may only be an Object or null: undefined).
Any help would be greatly appreciated.
In database.module.ts do a
#Module({
components: [...databaseProviders],
exports: [...databaseProviders],
})
export class DatabaseModule {}
three dots are required
Then in posts.module.ts
#Module({
imports: [DatabaseModule],
controllers: [PostsController],
components: [PostsService, ...postsProviders],
})
export class PostsModule {}
again three dots are required
in posts.providers.ts replace DB_CONNECTION with DB_PROVIDER
Why three dots ? If you will look in posts.providers.ts it exports an array, and you want your module to import each provider separately, not the array.
The example only shows loading of 1 locale which is bg.
How are we able to load all the locale so that we can change the locale dynamically. Thanks in advance!
http://plnkr.co/edit/Ucx0SlcmBfN9TRjrS5Ad?p=preview Plunker
[Short answer]
You can't change the locale of the Angular application dynamically, without recreating the module/component.
[Long version]
The locale of the Angular component is determined by the LOCALE_ID, which is injected through the Angular DI system. Considering the fact the Angular uses constructor based dependency injection, the component needs to be recreated in order to receive new LOCALE_ID value.
That being said, the only feasible solution to have components/modules with different locales is to wrap them with high order component that will provide different LOCALE_ID:
#Component({
selector: 'bg',
providers: [{
provide: LOCALE_ID,
useValue: 'bg-BG'
}, {
provide: IntlService,
useFactory: (localeId: string) => new CldrIntlService(localeId),
deps: [LOCALE_ID]
}],
template: `
<ng-content></ng-content>
`
})
export class BGComponent {
}
Here is runnable demo:
http://plnkr.co/edit/gmAWVLD1Yzn353QA1eDj?p=preview
Please note, that the plunker demonstrates how to place components with different locale on one page. As I mentioned, fully dynamic change of the locale is not possible (excluding the all possible hacks, of course). If there is a good solution out there using LOCALE_ID, I'd be more than happy to see it.