I'm trying to figure out how the "Repository Pattern" of TypeOrm in Nest works. I would like to have a resources file in which a local and a remote file hold the different entites, controllers, modules etc. See screenshot
When the app is building I`m getting the following error:
[Nest] 3186 - 11/19/2018, 10:44:43 PM [ExceptionHandler] No repository for "Project" was found. Looks like this entity is not registered in current "default" connection? +1ms
From the Nest and TypeORM documentation I can triangulate, that I have to tell the application where it can find the entities or at least this is what I believe the error is trying to tell me.
I'm using a .env to pull the config for TypeORM in:
TYPEORM_CONNECTION = postgres
TYPEORM_HOST = localhost
TYPEORM_USERNAME = xyz
TYPEORM_PASSWORD = xyz
TYPEORM_DATABASE = xyz
TYPEORM_PORT = 5432
TYPEORM_SYNCHRONIZE = true
TYPEORM_LOGGING = true
TYPEORM_ENTITIES = src/server/**/**.entity{.ts,.js}
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/project/project.module'
// sync
import {ProjectsSync} from './sync/projects.sync'
#Module({
imports: [
ProjectModule,
TypeOrmModule.forRoot(),
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();
}
}
Just a wild guess, have you tried:
TYPEORM_ENTITIES = ./server/**/**.entity{.ts,.js}
And/or switching the imports in app.module.ts putting the TypeOrmModule first:
#Module({
imports: [
TypeOrmModule.forRoot(),
ProjectModule,
AngularUniversalModule.forRoot(),
],
controllers: [],
providers:[JiraService, ProjectsSync],
})
export class ApplicationModule {}
In your .env file change
TYPEORM_ENTITIES = src/server/**/**.entity{.ts,.js}
to
TYPEORM_ENTITIES = /../**/*.entity.{js,ts}
in your app.module use:
const typeOrmConfig: TypeOrmModuleOptions = {
type: process.env.TYPEORM_CONNECTION,
host: process.env.TYPEORM_HOST,
port: process.env.TYPEORM_PORT,
username: process.env.TYPEORM_USERNAME,
password: process.env.TYPEORM_PASSWORD,
database: process.env.TYPEORM_DATABASE,
synchronize: process.env.TYPEORM_SYNCHRONIZE,
logging: process.env.TYPEORM_LOGGING,
entities: [__dirname + process.env.TYPEORM_ENTITIES]
}
#Module({
imports: [
TypeOrmModule.forRoot(typeOrmConfig),
ProjectModule,
AngularUniversalModule.forRoot(),
],
controllers: [],
providers:[JiraService, ProjectsSync],
})
export class ApplicationModule {}
Related
I have trouble with using mongoose in nest
error message is below :
Nest can't resolve dependencies of the movieModel (?). Please make sure that the argument DatabaseConnection at index [0] is available in the MongooseModule context.
Potential solutions:
If DatabaseConnection is a provider, is it part of the current MongooseModule?
If DatabaseConnection is exported from a separate #Module, is that module imported within MongooseModule?
movies.service.ts
import { Injectable } from '#nestjs/common';
import { CreateMovieDto } from './dto/create-movie.dto';
import { InjectModel } from '#nestjs/mongoose';
import { movie, movieDocument } from './schema/movie.schema';
import { Model } from 'mongoose';
#Injectable()
export class MoviesService {
constructor(
#InjectModel(movie.name) private movieModel: Model<movieDocument>,
) {}
async create(CreateMovieDto: CreateMovieDto): Promise<movie> {
return new this.movieModel(CreateMovieDto).save();
}
async getAll(): Promise<movie[]> {
return this.movieModel.find().exec();
}
app.modules.ts
import { Module } from '#nestjs/common';
import { MongooseModule } from '#nestjs/mongoose';
import { MoviesModule } from './movies/movies.module';
#Module({
imports: [
MoviesModule,
MongooseModule.forRoot('mongodb://localhost:27017/databasename', {
connectionName: 'movies',
}),
],
controllers: [],
providers: [],
})
export class AppModule {}
movie.module.ts
import { Module } from '#nestjs/common';
import { MongooseModule } from '#nestjs/mongoose';
import { MoviesController } from './movies.controller';
import { MoviesService } from './movies.service';
import { movieSchema } from './schema/movie.schema';
#Module({
imports: [
MongooseModule.forFeature([
{
name: 'movie',
schema: movieSchema,
collection: 'movies',
},
]),
],
controllers: [MoviesController],
providers: [MoviesService], //nestjs가 movieservice를 import하고 controller에 inject 한다.
})
export class MoviesModule {}
please help me figure this out
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 {}
The admin-bro-nestjs repository contains a comprehensive example with example with mongoose. But I need use it with typeorm and postgres.
I tried to adapt this example for typeorm:
// main.ts
import AdminBro from 'admin-bro';
import { Database, Resource } from '#admin-bro/typeorm';
import { NestFactory } from '#nestjs/core';
import { AppModule } from './app.module';
AdminBro.registerAdapter({ Database, Resource });
const bootstrap = async () => {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
}
bootstrap();
and
// app.module.ts
import { Module } from '#nestjs/common';
import { AdminModule } from '#admin-bro/nestjs';
import { TypeOrmModule, getRepositoryToken } from '#nestjs/typeorm';
import { Repository } from 'typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UserEntity } from './user/user.entity';
#Module({
imports: [
TypeOrmModule.forRoot({
type: 'postgres',
host: 'localhost',
port: 5432,
username: 'postgres',
password: 'password',
database: 'database_test',
entities: [UserEntity],
synchronize: true,
logging: false,
}),
AdminModule.createAdminAsync({
imports: [
TypeOrmModule.forFeature([UserEntity]),
],
inject: [
getRepositoryToken(UserEntity),
],
useFactory: (userRepository: Repository<UserEntity>) => ({
adminBroOptions: {
rootPath: '/admin',
resources: [
{ resource: userRepository },
],
},
auth: {
authenticate: async (email, password) => Promise.resolve({ email: 'test' }),
cookieName: 'test',
cookiePassword: 'testPass',
},
}),
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule { }
But on application start I get the following error:
NoResourceAdapterError: There are no adapters supporting one of the resource you provided
Does anyone have any experience putting all these libraries together?
I also got NoResourceAdapterError: There are no adapters supporting one of the resource you provided when I tried to integrate AdminBro with NestJS/Express/TypeORM (though I'm using MySQL instead Postgres). The solution posted in the admin-bro-nestjs Github issue which links to this question didn't help me.
The cause of NoResourceAdapterError for me simply was that UserEntity didn't extend BaseEntity. NestJS/TypeORM seems to work fine without extending BaseEntity but apparently it is required for AdminBro. You can see it used in the examples of the AdminBro TypeORM adapter documentation.
Here is an example which works for me.
// user.entity
import { Entity, BaseEntity, Column, PrimaryGeneratedColumn } from 'typeorm';
#Entity()
export class UserEntity extends BaseEntity{
#PrimaryGeneratedColumn()
id: number;
#Column()
name: string;
}
// app.module.ts
import { Module } from '#nestjs/common';
import { TypeOrmModule } from '#nestjs/typeorm';
import { AdminModule } from '#admin-bro/nestjs';
import { Database, Resource } from '#admin-bro/typeorm';
import AdminBro from 'admin-bro'
AdminBro.registerAdapter({ Database, Resource });
#Module({
imports: [
TypeOrmModule.forRoot({
// ...
}),
AdminModule.createAdmin({
adminBroOptions: {
resources: [UserEntity],
rootPath: '/admin',
},
})
],
// ...
})
How can we inject connection dependencies of the subscriber with yml files .
my files are :
ormconfig.yml
default:
type: 'postgres'
host: 'localhost'
port: 5432
username: 'postgres'
password: 'root'
database: 'hiring_db'
entities: ["dist/**/*.entity{.ts,.js}"]
synchronize: true
logging: ["query","error"]
logger: "file"
extra: { timezone: "+5:30" }
migrations: ["src/migrations/*.ts"]
cli: {
migrationDir: 'src/migrations'
}
subscribers: ["src/**/*.subscriber{.ts,.js}"]
JobPostingModule.ts
import { Module } from '#nestjs/common';
import { JobPostingController } from './job-posting.controller';
import { JobPostingService } from './job-posting.service';
import { AuthModule } from '../auth/auth.module';
import { RecruitmentService } from '../recruitment/recruitment.service';
#Module({
imports: [
AuthModule
],
controllers: [JobPostingController],
providers: [JobPostingService, RecruitmentService]
})
export class JobPostingModule {}
JobSubscriber.ts
import { Injectable } from '#nestjs/common';
import { InjectConnection } from '#nestjs/typeorm';
import { Jobs } from 'src/entities/job-posting.entity';
import { Connection, EntitySubscriberInterface, getConnection, InsertEvent, UpdateEvent } from 'typeorm';
import { JobPostingService } from './job-posting.service';
#Injectable()
export class JobSubscriber implements EntitySubscriberInterface {
constructor(private readonly connection: Connection) {
connection.subscribers.push(this); // <---- THIS
}
listenTo() {
return Jobs;
}
afterInsert(event: InsertEvent<Jobs>) {
console.log('Hi guys!');
};
afterUpdate(event: UpdateEvent<any>) {
console.log('Hi guys!');
}
}
I am getting this error Nest can't resolve dependencies of the JobSubscriber (?). Please make sure that the argument Connection at index [0] is available in the AppModule context.
Potential solutions:
- If Connection is a provider, is it part of the current AppModule?
- If Connection is exported from a separate #Module, is that module imported within AppModule?
#Module({
imports: [ /* the Module containing Connection */ ]
})
do not use subscribers: ["src/**/*.subscriber{.ts,.js}"]
just add connection.subscribers.push(this); logic
and use the subscriber as a module Provider.
You can refer to the official NestJS documentation for this problem.
import { Module } from '#nestjs/common';
import { TypeOrmModule } from '#nestjs/typeorm';
#Module({
imports: [
TypeOrmModule.forRoot(),
],
})
export class AppModule {}
Once you imported the TypeOrmModule you can use Connection as a provider everywhere.
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],
})