I have created an interceptor as shown below that I wish to use globally. I added the interceptor to my module and set it up so that nest js should handle the DI for me per NestJS Docs, however when I make a request to my service, I get an error indicating Cannot read property log of undefined so it appears that the DI is not being taken care of by NestJS.
Interceptor Code:
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '#nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { LoggingService } from './logging.service';
#Injectable()
export class AuthInterceptor implements NestInterceptor {
constructor(private readonly loggingService: LoggingService) { }
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
return next
.handle()
.pipe(
map((response) => {
this.loggingService.log('Responded successfully');
return response;
})
);
}
}
Interceptor Module:
import { Module } from '#nestjs/common';
import { APP_INTERCEPTOR } from '#nestjs/core';
import { AuthInterceptor } from './auth.interceptor';
import { LoggingService } from './logging.service';
#Module({
providers: [
LoggingService,
{
provide: APP_INTERCEPTOR,
useClass: AuthInterceptor,
},
],
})
export class AuthInterceptorModule {}
My app.module.ts at the root of my application imports the AuthInterceptorModule. I am assuming I am messing something up but it is not clear to me how to fix this DI issue.
I was able to resolve this one on my own after finding that my LoggingService relied on another dependency that was request scoped. Since there was a request scoped dependency in my interceptor, this meant that my interceptor also had to be request scoped.
The change to the code was simple and only required that I change the AuthInterceptorModule from:
import { Module } from '#nestjs/common';
import { APP_INTERCEPTOR } from '#nestjs/core';
import { AuthInterceptor } from './auth.interceptor';
import { LoggingService } from './logging.service';
#Module({
providers: [
LoggingService,
{
provide: APP_INTERCEPTOR,
useClass: AuthInterceptor,
},
],
})
export class AuthInterceptorModule {}
to
import { Module } from '#nestjs/common';
import { APP_INTERCEPTOR, Scope } from '#nestjs/core';
import { AuthInterceptor } from './auth.interceptor';
import { LoggingService } from './logging.service';
#Module({
providers: [
LoggingService,
{
provide: APP_INTERCEPTOR,
scope: Scope.REQUEST,
useClass: AuthInterceptor,
},
],
})
export class AuthInterceptorModule {}
Related
I have CurrencyService that I want to use in another module. Here's what I did:
import { HttpModule } from '#nestjs/axios';
import { Module } from '#nestjs/common';
import { ScheduleModule } from '#nestjs/schedule';
import { TypeOrmModule } from '#nestjs/typeorm';
import { CurrencyRepository } from './currency.repository';
import { CurrencyService } from './currency.service';
#Module({
imports: [
HttpModule,
ScheduleModule.forRoot(),
TypeOrmModule.forFeature([CurrencyRepository]),
],
exports: [CurrencyService],
providers: [CurrencyService],
})
export class CurrencyModule {}
In my CurrencyService, I have injected a repository and another service:
export class CurrencyService {
constructor(
private currencyRepository: CurrencyRepository,
private httpService: HttpService,
) {}
async getCurrency(base: string, target: string): Promise<Currency> {
console.log(this.currencyRepository);
.....
My problem is that when I import the CurrencyModule, and inject the CurrencyService into the service of another module, currencyRepository and httpService are both undefined.
There is no error on startup, it's just that the dependencies are undefined which causes error on runtime.
I also tried something like this:
import { HttpModule } from '#nestjs/axios';
import { Module } from '#nestjs/common';
import { ScheduleModule } from '#nestjs/schedule';
import { TypeOrmModule } from '#nestjs/typeorm';
import { CurrencyRepository } from './currency.repository';
import { CurrencyService } from './currency.service';
#Module({
imports: [
HttpModule,
ScheduleModule.forRoot(),
TypeOrmModule.forFeature([CurrencyRepository]),
],
exports: [
CurrencyService,
TypeOrmModule.forFeature([CurrencyRepository]),
HttpModule,
],
providers: [CurrencyService],
})
export class CurrencyModule {}
I got the same undefined dependencies.
The #Injectable() decorator is missing from the CurrencyService. This decorator (or any decorator really) is what tells Typescript to emit the metadata of the controller that Nest is reading, so it is crucial to have it in place.
error (cont): Please make sure that the argument PrismaService at index [0] is available in the Assoc_Page_TagModule context.
There are no errors in the code.
When I attempt > npm run start:dev
I initially get: Found 0 errors. Watching for file changes.
Then an error:
[ExceptionHandler] Nest can't resolve dependencies of the Assoc_Page_TagService (?). Please make sure that the argument PrismaService at index [0] is available in the Assoc_Page_TagModule context.
What is the argument at index [0]? Why is it expecting an argument?
Assoc_Page_Tag.service.ts
import { Injectable } from '#nestjs/common';
import { PrismaService } from '../database';
import { Prisma } from '#prisma/client';
#Injectable()
export class Assoc_Page_TagService {
constructor(private readonly prisma: PrismaService) {}
Assoc_Page_TagsAll() {
return Promise.all([
this.prisma.assoc_Page_Tag.findMany()]).then(([records, total]) => {
return {
records,
metadata: { total },
};
});
}
Assoc_Page_Tag.module.ts
import { Module } from '#nestjs/common';
import { Assoc_Page_TagController } from './Assoc_Page_Tag.controller';
import { Assoc_Page_TagService } from './Assoc_Page_Tag.service';
#Module({
imports: [],
controllers: [Assoc_Page_TagController],
providers: [Assoc_Page_TagService],
exports: [Assoc_Page_TagService],
})
export class Assoc_Page_TagModule {}
Assoc_Page_Tag.controller.ts
import {
Body,Controller,Get,Param,ParseIntPipe,Put,
} from '#nestjs/common';
import { Assoc_Page_TagService } from './Assoc_Page_Tag.service';
import { RESOURCE_BASE_ROUTE } from '../constant';
import { Prisma } from '#prisma/client';
const Route = RESOURCE_BASE_ROUTE.assoc_Page_Tag
#Controller()
export class Assoc_Page_TagController {
constructor(private readonly assoc_page_tagService: Assoc_Page_TagService) {}
#Get(`${Route}`)
all() {
return this.assoc_page_tagService.Assoc_Page_TagsAll();
}
}
app.module.ts
import { Module } from '#nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { Assoc_Page_TagModule } from './Assoc_Page_Tag';
#Module({
imports: [
Assoc_Page_TagModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Missing reference to PrismaModule - which exports PrismaService
import { Module } from '#nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { PrismaModule } from './database';
import { Assoc_Page_TagModule } from './Assoc_Page_Tag';
#Module({
imports: [
PrismaModule,
Assoc_Page_TagModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
I'm really confused, I got this weird error and I have no idea.
Error: Nest can't resolve dependencies of the JobsService (?). Please make sure that the argument JobModel at index [0] is available in the AppModule context.
app.module.ts
import { Module } from '#nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { MongooseModule } from '#nestjs/mongoose';
import { JobsModule } from './jobs/jobs.module';
import { JobsService } from './jobs/jobs.service';
import { JobsController } from './jobs/jobs.controller';
import config from './config/config';
#Module({
imports: [JobsModule, MongooseModule.forRoot(config.mongoURI, {
useFindAndModify: false,
})],
controllers: [AppController, JobsController],
providers: [AppService, JobsService],
})
export class AppModule {}
/jobs/jobs.module.ts
import { Module } from '#nestjs/common';
import { MongooseModule } from '#nestjs/mongoose';
import { JobsService } from './jobs.service';
import { JobsController } from './jobs.controller';
import { JobsSchema } from './schemas/jobs.schema';
#Module({
imports: [MongooseModule.forFeature([{ name: 'Job', schema: JobsSchema }])],
controllers: [JobsController],
providers: [JobsService],
})
export class JobsModule {}
/job/job.controller.ts
import { Controller, Get, Post, Put, Delete, Body, Param } from '#nestjs/common';
import { JobsService } from './jobs.service';
import { IJobs } from './interfaces/jobs.interface';
#Controller('jobs')
export class JobsController {
constructor(private readonly jobsService: JobsService){}
#Get()
findAll():Promise<IJobs[]> {
return this.jobsService.findAll();
}
}
/job/jobs.service.ts
import { Injectable } from '#nestjs/common';
import { InjectModel } from '#nestjs/mongoose';
import { Model } from 'mongoose';
import { IJobSchema } from './schemas/jobs.schema';
import { IJobs } from './interfaces/jobs.interface';
#Injectable()
export class JobsService {
constructor(#InjectModel('Job') private readonly JobsModel: Model<IJobSchema>){}
async findAll():Promise<IJobs[]> {
return await this.JobsModel.find();
}
}
you already declared JobsService in your JobModule, delete it from Appmodule providers
import { Module } from '#nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { MongooseModule } from '#nestjs/mongoose';
import { JobsModule } from './jobs/jobs.module';
import { JobsService } from './jobs/jobs.service';
import { JobsController } from './jobs/jobs.controller';
import config from './config/config';
#Module({
imports: [JobsModule, MongooseModule.forRoot(config.mongoURI, {
useFindAndModify: false,
})],
controllers: [AppController, JobsController],
providers: [AppService], // Here..
})
export class AppModule {}
this error occur when application is started.
The terminal is not showing any error but in the browser console.
The last action was i import JwtHelperService from '#auth0/angular-jwt'
The project is in Nodejs, express 4.16.4 and angular 7.2.0
I have included some code
please help me to find the error
thank you in advance
auth.service.ts
import { Injectable } from "#angular/core";
import { Observable } from "rxjs";
import "rxjs/Rx";
import { JwtHelperService } from "#auth0/angular-jwt";
import { map } from "rxjs/operators";
import "core-js/es7/reflect";
import { HttpClient } from "#angular/common/http";
const jwt = new JwtHelperService();
export class AuthService {
#Injectable()
private decodedToken;
constructor(private http: HttpClient) {}
public register(userData: any): Observable<any> {
return this.http.post("/api/v1/users/register", userData);
}
public login(userData: any): Observable<any> {
return this.http.post("/api/v1/users/auth", userData).map(token => {
//debugger;
return this.saveToken(token);
});
}
private saveToken(token): string {
//debugger;
this.decodedToken = jwt.decodeToken(token);
localStorage.setItem("bwm_auth", token.token);
localStorage.setItem("bwm_meta", JSON.stringify(this.decodedToken));
return token;
}
}
app.module.ts
import { NgModule } from "#angular/core";
import { CommonModule } from "#angular/common";
import { FormsModule, ReactiveFormsModule } from "#angular/forms";
import { Routes, RouterModule } from "#angular/router";
import { LoginComponent } from "./login/login.component";
import { RegisterComponent } from "./register/register.component";
import { AuthService } from "./shared/auth.service";
const routes: Routes = [
{ path: "login", component: LoginComponent },
{ path: "register", component: RegisterComponent }
];
#NgModule({
declarations: [LoginComponent, RegisterComponent],
imports: [
RouterModule.forChild(routes),
FormsModule,
CommonModule,
ReactiveFormsModule
],
exports: [],
providers: [AuthService]
})
export class AuthModule {}
error on browser
compiler.js:2430 Uncaught Error: Can't resolve all parameters for AuthService: (?).
at syntaxError (compiler.js:2430)
at CompileMetadataResolver.push../node_modules/#angular/compiler/fesm5/compiler.js.CompileMetadataResolver._getDependenciesMetadata (compiler.js:18984)
at CompileMetadataResolver.push../node_modules/#angular/compiler/fesm5/compiler.js.CompileMetadataResolver._getTypeMetadata (compiler.js:18877)
at CompileMetadataResolver.push../node_modules/#angular/compiler/fesm5/compiler.js.CompileMetadataResolver._getInjectableTypeMetadata (compiler.js:19099)
at CompileMetadataResolver.push../node_modules/#angular/compiler/fesm5/compiler.js.CompileMetadataResolver.getProviderMetadata (compiler.js:19108)
at compiler.js:19046
at Array.forEach (<anonymous>)
at CompileMetadataResolver.push../node_modules/#angular/compiler/fesm5/compiler.js.CompileMetadataResolver._getProvidersMetadata (compiler.js:19006)
at CompileMetadataResolver.push../node_modules/#angular/compiler/fesm5/compiler.js.CompileMetadataResolver.getNgModuleMetadata (compiler.js:18725)
at CompileMetadataResolver.push../node_modules/#angular/compiler/fesm5/compiler.js.CompileMetadataResolver.getNgModuleSummary (compiler.js:18555)
image of error in browser
#Injectable() should be placed before the class definition
#Injectable()
export class AuthService {
}
You should first add #Injectable to your AuthService
But this error indicates that the DI cannot resolve the requested parameter asked by the AuthService (HttpClient).
To resolve this issue, you need to include the HttpClient module in your AppModule as this code snippet shows
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { HttpClientModule } from '#angular/common/http';
#NgModule({
imports: [
BrowserModule,
// import HttpClientModule after BrowserModule.
HttpClientModule,
],
declarations: [
AppComponent,
],
bootstrap: [ AppComponent ]
})
export class AppModule {}
You can see their full documentation here HttpModule
I'm new to nest and I have run into an error which is not really decodable for me. I tried to follow the nest example, but no luck.
[tsl] ERROR in /Users/user/Documents/development/sprinta/src/server/app.module.ts(12,5)
[0] TS2322: Type '(DynamicModule | typeof ProjectModule)[]' is not assignable to type 'Type<any> | DynamicModule | Promise<DynamicModule> | ForwardReference<any>'.
[0] Type '(DynamicModule | typeof ProjectModule)[]' is not assignable to type 'ForwardReference<any>'.
[0] Property 'forwardRef' is missing in type '(DynamicModule | typeof ProjectModule)[]'.
app.module.ts
import { Module } from '#nestjs/common';
import { TypeOrmModule } from '#nestjs/typeorm';
import { AngularUniversalModule } from './modules/angular-universal/angular-universal.module';
import { JiraService } from './services/jira.service'
// modules
import { ProjectModule } from './resources/local/projects/project.module'
// sync
import {ProjectsSync} from './sync/projects.sync'
#Module({
imports: [
[TypeOrmModule.forRoot(), ProjectModule],
AngularUniversalModule.forRoot(),
],
controllers: [],
providers:[JiraService, ProjectsSync],
})
export class ApplicationModule {}
project.module.ts
import { Module } from '#nestjs/common';
import { TypeOrmModule } from '#nestjs/typeorm';
import { ProjectService } from './project.service';
import { ProjectController } from './project.controller';
import { Project } from './project.entity';
#Module({
imports: [TypeOrmModule.forFeature([Project])],
providers: [ProjectService],
controllers: [ProjectController],
})
export class ProjectModule {}
project.service.ts
import { Injectable, Inject } from '#nestjs/common';
import { InjectRepository } from '#nestjs/typeorm';
import { Repository } from 'typeorm';
import { Project } from './project.entity';
#Injectable()
export class ProjectService {
constructor(
#InjectRepository(Project)
private readonly projectRepository: Repository<Project>,
) {}
async findAll(): Promise<Project[]> {
return await this.projectRepository.find();
}
}
project.entity.ts
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';
#Entity()
export class Project {
#PrimaryGeneratedColumn()
id: number;
#Column({ length: 500 })
name: string;
}
project.controller.ts
import { Controller, Get } from '#nestjs/common';
import { ProjectService } from './project.service';
import { Project } from './project.entity';
#Controller('project')
export class ProjectController {
constructor(private readonly projectService: ProjectService) {}
#Get()
findAll(): Promise<Project[]> {
return this.projectService.findAll();
}
}
Thanks for the help
You have an extra nested array around TypeOrmModule.forRoot() and ProjectModule. The #Module call should read:
#Module({
imports: [
TypeOrmModule.forRoot(), ProjectModule,
AngularUniversalModule.forRoot(),
],
controllers: [],
providers:[JiraService, ProjectsSync],
})