Closed pirmax closed 6 years ago
You need to provide UserService
in a module. Adding UserService
to providers in application.module.ts
should work
Thanks for reply @ryanswart but I've this error now:
Error: Nest can't resolve dependencies of the UserService (?). Please make sure that the argument at index [0] is available in the current context.
Check https://docs.nestjs.com/techniques/database - you need to add TypeOrmModule.forFeature([UserEntity])
to your module imports
Now I have this files and I get this error message:
[ExceptionHandler] Nest can't resolve dependencies of the AuthService (?). Please make sure that the argument at index [0] is available in the current context.
import { Module } from "@nestjs/common";
import { ApplicationController } from "controllers/application.controller";
import { ApplicationService } from "services/application.service";
import { TypeOrmModule } from "@nestjs/typeorm";
import { UserModule } from "./user.module";
import { AuthModule } from "./auth.module";
import { AuthService } from "services/auth.service";
import { UserService } from "services/user.service";
import { UserController } from "controllers/user.controller";
import { UserEntity } from "entities/user.entity";
@Module({
imports: [
AuthModule,
UserModule,
TypeOrmModule.forFeature([
UserEntity,
]),
TypeOrmModule.forRoot({
type: "mysql",
host: "",
port: 3306,
username: "",
password: "",
database: "",
entities: [__dirname + "/../entities/*.entity{.ts,.js}"],
synchronize: true,
}),
],
controllers: [
ApplicationController,
UserController,
],
providers: [
ApplicationService,
UserService,
AuthService,
],
})
export class ApplicationModule {}
import { Module } from "@nestjs/common";
import { UserController } from "controllers/user.controller";
import { UserService } from "services/user.service";
@Module({
controllers: [
UserController,
],
providers: [
UserService,
],
})
export class UserModule {}
import { Module } from "@nestjs/common";
import { JwtModule } from "@nestjs/jwt";
import { AuthService } from "services/auth.service";
@Module({
imports: [
JwtModule.register({
secretOrPrivateKey: "key12345",
}),
],
providers: [
AuthService,
],
})
export class AuthModule {}
import { Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Repository } from "typeorm";
import { UserEntity } from "entities/user.entity";
@Injectable()
export class UserService {
constructor(
@InjectRepository(UserEntity)
private readonly userRepository: Repository<UserEntity>,
) {}
async findAll(): Promise<UserEntity[]> {
return await this.userRepository.find();
}
}
import { Injectable } from "@nestjs/common";
import { JwtService } from "@nestjs/jwt";
import { TokenJwtInterface } from "interfaces/token-jwt.interface";
@Injectable()
export class AuthService {
private tokenType;
constructor(private readonly jwtService: JwtService) {
this.tokenType = "bearer";
}
public generateTokenJwt(
payload: object,
expiresIn: number,
): TokenJwtInterface {
const accessToken = this.jwtService.sign(payload);
return {
access_token: accessToken,
token_type: this.tokenType,
refresh_token: "",
expires_in: expiresIn,
};
}
}
AuthModule
should provide AuthService
, not ApplicationModule
because AuthModule
imports JwtModule, which exposes JwtService. If you imported JwtModule
in ApplicationModule
, it would work, but that wouldn't be good separation of concerns
For those who might be interested, I ran into the same problem and was able to solve it by including TypeOrmModule.forFeature()
in the imports section of auth.module.ts
file.
import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { JwtStrategy } from './jwt.strategy';
import { UserService } from '../../user/user.service';
import { UserEntity } from '../../user/user.entity';
import { TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [
TypeOrmModule.forFeature([UserEntity]),
PassportModule.register({ defaultStrategy: 'jwt' }),
JwtModule.register({
secretOrPrivateKey: 'secret',
signOptions: { expiresIn: '30m' },
}),
],
controllers: [AuthController],
providers: [AuthService, JwtStrategy, UserService],
})
export class AuthModule {}
Previously (when error occurred), I had in users.controller.ts
:
// Problematic nesting in services object:
constructor(private readonly services: { users: UsersService }) { }
What was helpful for me:
// Flat variable according to documentation:
constructor(private readonly userService: UsersService) { }
please check your app.module.ts for the controllers and providers arrays. i was using the cli to generate all the different elements and by default these arrays are updated with the new 'components'. problem is that once you create your own custom module you include these arrays and their content inside. and they are only visible in that specific scope. so if for example you have UserService element inside a services folder inside your model then this elemet is hidden from the global scope.
In my opinion its a bit fkd up because of circular dependency injection and the entire hirarcy Nestjs is build upon or maybe i am mistaken to think it this way, but heck, it solved my issue than i'm glad
The documentation is lacking for someone like me, mentally challenged.
I cannot get any of this to work either...
app.module.ts
@Module({
imports: [
HttpModule,
AuthenticationModule,
UserModule,
],
controllers: [AppController],
})
export class AppModule {}
user.module.ts
@Module({
providers: [UserService],
exports: [UserService],
})
export class UserModule {}
auth.module.ts
@Module({
imports: [
HttpModule,
UserModule,
PassportModule,
JwtModule.register({ secret: process.env.JWT_SECRET }),
],
providers: [AuthenticationService, LocalStrategy],
controllers: [AuthenticationController],
exports: [AuthenticationService],
})
export class AuthenticationModule {}
auth.service.ts
@Injectable()
export class AuthenticationService implements IAuthenticationService {
constructor(
protected readonly userService: IUserService,
protected readonly jwtService: JwtService,
) {}
/**
* Attempts to authenticate a user with a given email and password combination.
*
* @param email
* @param password
*/
public async authenticate(email: string, password: string): Promise<Session> {
try {
const user = await this.userService.getAuthenticationDetails(email);
if (isNil(user)) {
throw new Error(NOT_FOUND_ERR);
}
if (!comparePassword(password, user.password, user.salt)) {
throw new Error(MISMATCH_ERR);
}
return sessionFactory(user._id.toString(), user.email, user.userType);
} catch (err) {
throw err;
}
}
/**
* Creates a JWT from a session
*
* @param session Session object to produce the JWT out of
*/
public signJWT(session: ISession): string {
return this.jwtService.sign(session);
}
}
Now, when I try to run npm start
I get this:
Nest can't resolve dependencies of the AuthenticationService (?, JwtService). Please make sure that the argument at index [0] is available in the AuthenticationModule context. +16ms
The docs say that I just need to import the module. Yet nothing is working. So are the docs wrong? What do I do here? Do I need to set authentication module providers to have UserService
in there? If so, what's the point of modules in that case if I can dump EVERYTHING into the main app.module.ts
instead? Because this seems to be way easier.
@TheImpressionist - check IUserService
vs. UserService
. The error indicates that Nest doesn't have an injectable associated with the token IUserService
. Can't tell without knowing more, but perhaps it's simply changing the constructor line to protected readonly userService: UserService
Also
The documentation is lacking for someone like me, mentally challenged.
I'm interested in addressing any shortcomings in the documentation. What information was lacking/confusing (maybe you'll know better after getting this resolved) ?
I'm interested in addressing any shortcomings in the documentation. What information was lacking/confusing (maybe you'll know better after getting this resolved) ?
@johnbiundo I realize that this is not really the place to discuss this (i should open an issue) but since i was browsing this issue and you just asked, so here are two quick personal suggestions about the docs:
Having the same issue as @TheImpressionist -- and @kgish 's solution resolves it.
@Module({
imports: [
UserModule,
TypeOrmModule.forFeature([User]) // <-- why does this need to be here???
],
providers: [AuthService, UserService],
exports: [AuthService]
})
export class AuthModule {}
It seems odd to me that the dependencies of the UserModule have to also be specified in the AuthModule. Do the module's import dependencies normally have to be explicitly configured everywhere the module is used - isn't that a leaky abstraction? Or is this only an issue for the injected TypeOrmModule?
@mkelandis your UserModule
has to export TypeOrmModule
. Then, TypeOrmModule.forFeature([User])
won't be required
I dont know if im helping anyone but in my implementation I had forgot to import HttpModule
in app.module.ts
. When I imported it worked fine. Hope it helped someone.
In case it helps anyone, my issue was needing to put a service in the 'exports' array of it's parent module, then in the module that consumed said service I needed to include the service in the imports AND providers array. Not sure if this is best practice but it is the only thing I found that fixed my issue.
I believe that the "Can't resolve dependencies" error is way too generic. Is there any way to make it more clear as to what is not correct?
@kamilmysliwiec
That worked for me.
But I would expect having TypeOrmModule.forRoot
and even export it in the AppModule
should be enough.
For me that would mean, in theory I have to export TypeOrmModule in any module with resolvers/repositories that are required in another module. Possible, but not intuitive in my eyes. 🙈
I think anyway this is not a nestjs problem rather than a TypeOrm problem.
I'm submitting a...
Current behavior
Trying to use my UserService.ts and AuthService.ts in my UserController.ts, but I get the following error:
[ExceptionHandler] Nest can't resolve dependencies of the UserController (?, +). Please make sure that the argument at index [0] is available in the current context.
Minimal reproduction of the problem with instructions
application.module.ts
user.module.ts
user.service.ts
auth.module.ts
auth.service.ts
user.controller.ts
What is the motivation / use case for changing the behavior?
Bugfix?
Environment