Inject service into guard in Nest.JS
To inject service in guard.You can create a global module.
// ApiModule
import {Module,Global} from '@nestjs/common';
import {KeyService} from '../';
@Global()
@Module({
providers: [ KeyService ],
exports: [KeyService]
})
export class ApiModule {}
Then inject service into guard like this
// guard
export class ApiGuard implements CanActivate {
constructor(@Inject('KeyService') private readonly KeyService) {}
}
async canActivate(context: ExecutionContext) {
// your code
throw new ForbiddenException();
}
Now the problem can be solved.But I have another problem.I want to inject something into service but got this error:
Nest can't resolve dependencies of the AuthGuard (?, +). Please make sure that the argument at index [0] is available in the current context.
And here is my solution:
To Inject other dependency in KeyService,like nestjs docs say.
global guards registered from outside of any module (with useGlobalGuards() as in the example above) cannot inject dependencies since this is done outside the context of any module.
This is their sample:
// app.module.js
import { Module } from '@nestjs/common';
import { APP_GUARD } from '@nestjs/core';
@Module({
providers: [
{
provide: APP_GUARD,
useClass: RolesGuard,
},
],
})
export class ApplicationModule {}
It worked.Now I can use guard global without dependency error.
Services used in the guard must be exported in its module. Providing service is not enough!
Maybe it's too late, but I ran the same issue and find a solution. Maybe there is a better one, but it's working properly for me:
Define KeysModule as a global module, you can check how to do it in nestjs docs: https://docs.nestjs.com/modules
After You can do this:
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
@Injectable()
export class ApiGuard implements CanActivate {
constructor(
@Inject('KeyService')
private readonly ks
) {}
const key = await this.ks.findKey();
"YOUR_CODE_HERE..."
}
Hope it's help to you or somebody who will stuck with this in the future.
As of NestJS v8 it seems injecting the service as answered by zsoca in the accepted answer doesn't work anymore.
The working solution for NestJS 8 is by providing a class reference instead of a string:
constructor(@Inject(KeyService) private keyService: KeyService) {}