スキップしてメイン コンテンツに移動

[Angular][Nest.js] Add TypeOrm

Intro

This time I added TypeOrm into the Nest.js project.
[Angular 10 + NgRx + Nest.js] Create project

Use TypeOrm

Install

To use TypeOrm I installed some packages. 

And to integrate the Nest.js project, I add an additional package.
npm install --save @nestjs/typeorm typeorm pg
Database | NestJS - A progressive Node.js framework

Configuration

Last time I used "ormconfig.json" for TypeOrm configuration. In Nest.js projects, I also could write them in "app.module.ts".

server/app.module.ts


import { Module } from '@nestjs/common';
import { AngularUniversalModule } from '@nestjs/ng-universal';
import { TypeOrmModule } from '@nestjs/typeorm';
import { join } from 'path';
import { Workflow } from './entities/workflow.entity';

@Module({
  imports: [
    AngularUniversalModule.forRoot({
      viewsPath: join(process.cwd(), 'dist/browser'),
      bundle: require('../server/main'),
      liveReload: false
    }),
    TypeOrmModule.forRoot({
      type: "postgres",
      host: "localhost",
      port: 5432,
      username: "test",
      password: "test",
      database: "Example",
      entities: [Workflow],
      synchronize: true,
      logging: true,
      cache: false
    })
  ],
  controllers: [],
  providers: []
})
export class ApplicationModule {}

My choice

But I choosed using "ormconfig.json". When I migrated Database by migration files, I had to use TypeOrm commands. But TypeOrm commands couldn't read "app.module.ts". So I must add the "ormconfig.json" file anyway.

ormconfig.json


{
    "type": "postgres",
    "host": "localhost",
    "port": 5432,
    "username": "test",
    "password": "test",
    "database": "Example",
    "entities": ["dist/**/entities/*.entity{.ts,.js}"],
    "migrations": ["server/migrations/*.{.ts,.js}"],
    "synchronize": true,
    "logging": true,
    "cache": false,
    "cli": {
        "entitiesDir": "server/entities",
        "migrationsDir": "server/migrations"
    }
}

So I removed the configure informations from "app.module.ts".

server/app.module.ts


...
@Module({
  imports: [
...
    TypeOrmModule.forRoot()
  ],
  controllers: [],
  providers: []
})
export class ApplicationModule {}

Add an Entity class

server/entities/workflow.entity.ts


import {Entity, PrimaryGeneratedColumn, Column, OneToMany, UpdateDateColumn} from "typeorm";

@Entity("Workflow")
export class Workflow {
    @PrimaryGeneratedColumn()
    id: number = -1;
    @Column({ type: 'text', nullable: false })
    createUserMail: string = '';
    @Column({ type: 'timestamp with time zone', nullable: true })
    circulationLimit: Date|null = null;
    @Column({ type: 'timestamp with time zone', nullable: false })
    lastUpdateDate: Date = new Date();
    
    public create(createUserMail: string, circulationLimit: Date|null) {
        if (createUserMail == null ||
            createUserMail.length <= 0) {
            throw new Error("Can not set createUserMail empty");
        }
        this.createUserMail = createUserMail;
        this.update(circulationLimit);
    }
    public update(circulationLimit: Date|null) {
        this.circulationLimit = circulationLimit;
        this.lastUpdateDate = new Date();
    }
}

Use "nest generate"

To access TypeOrm classes, I wanted to add classes into the Nest.js project. But when I did "nest generate" command, the created files were put into "src" directory. How to change to "server"? I had to add nest-cli.json like below.

nest-cli.json


{
    "collection": "@nestjs/schematics",
    "sourceRoot": "server"
}

After I did this, the files could be into "server" directory.

Add "@nestjs/testing"

After I generated some classes(ex. controller, service, etc.), I got an error. It was because the test classes needed "@nestjs/testing" package.
npm install --save-dev @nestjs/testing

Access the Database by Repositories

Access the Database(failed)

I added one controller class and one service class to access the Database.

server/workflow/workflow.controller.ts


import { Controller, Get } from '@nestjs/common';
import { WorkflowService } from './workflow.service';
import { Workflow } from '../entities/workflow.entity';

@Controller('workflow')
export class WorkflowController {
    constructor(private readonly service: WorkflowService) {
    }
    @Get("search")
    public async getWorkflowItems(): Promise<Workflow[]> {
        return await this.service.findAll();
    }
}

server/workflow/workflow.service.ts


import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Workflow } from '../entities/workflow.entity';
import { Repository } from 'typeorm';
import { of } from 'rxjs';

@Injectable()
export class WorkflowService {
    constructor(
        @InjectRepository(Workflow)
        private workflowRepositiory: Repository<Workflow>
    ){}
    public findAll(): Promise<Workflow[]> {
        return this.workflowRepositiory.find();
    }
}

server/app.module.ts


...
import { WorkflowController } from './workflow/workflow.controller';
import { WorkflowService } from './workflow/workflow.service';
import { Workflow } from './entities/workflow.entity';

@Module({
  imports: [
...
  ],
  controllers: [WorkflowController],
  providers: [WorkflowService]
})
export class ApplicationModule {}

OK. I started serving the project. 

...And I got an error.
...
[Nest] 17376   - 07/11/2020, 8:22:27 PM   [ExceptionHandler] Nest can't resolve dependencies of the WorkflowService (?). Please make sure that the argument WorkflowRepository at index [0] is available in the ApplicationModule context.

Potential solutions:
- If WorkflowRepository is a provider, is it part of the current ApplicationModule?
- If WorkflowRepository is exported from a separate @Module, is that module imported within ApplicationModule?
  @Module({
    imports: [ /* the Module containing WorkflowRepository */ ]
  })
 +570ms
Error: Nest can't resolve dependencies of the WorkflowService (?). Please make sure that the argument WorkflowRepository at index [0] is available in the ApplicationModule context.

Potential solutions:
- If WorkflowRepository is a provider, is it part of the current ApplicationModule?
- If WorkflowRepository is exported from a separate @Module, is that module imported within ApplicationModule?
  @Module({
    imports: [ /* the Module containing WorkflowRepository */ ]
  })

    at Injector.lookupComponentInParentModules (C:\Users\example\Documents\workspace\proofreading-workflow\node_modules\@nestjs\core\injector\injector.js:190:19)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
[nodemon] app crashed - waiting for file changes before starting...

Resolve the dependencies

To resolve the dependencies of Repository class, I had to add a module.

server/app.module.ts


...
import { Workflow } from './entities/workflow.entity';

@Module({
  imports: [
...
    TypeOrmModule.forRoot(),
    TypeOrmModule.forFeature([Workflow])
  ],
  controllers: [ProofreaderController, WorkflowController],
  providers: [ProofreaderService, WorkflowService]
})
export class ApplicationModule {}

Finally, I could access the Database :).

Resources

コメント

このブログの人気の投稿

[Angular][ASP.NET Core] Upload chunked files

Intro I wanted to send files to Web application (made by ASP.NET Core). If the file size had been small, I didn't need do any special things. But when I tried to send a large file, the error was occurred by ASP.NET Core's limitation. Though I could change the settings, but I didn't want to do that, because I hadn't known the file sizes what would been actually using. So I splitted the data into chunks first, and sent them. After receiving all chunks, I merged them into one file. There might be some libraries or APIs (ex. Stream API) what did them automatically, but I couldn't find them. What I did [ASP.NET Core] Make CORS enabled [Angular] Split a large file into chunks [Angular][ASP.NET Core] Send and receive data as form data [ASP.NET Core] Merge chunks into one file [ASP.NET Core] Make CORS enabled Because the client side application(Angular) and the server side application(ASP.NET Core) had been separated, I had to make CORS(Cross-Origin Requests)

[Nest.js] Use WebSocket with ws

Intro Until last time , I had used node-web-rtc to try WebRTC. But because the example was a little complicated for I understood the core functions of using WebRTC. So I look for other frameworks or libraries. PeerJS is a famous library for WebRTC. peers/peerjs: Peer-to-peer data in the browser. - GitHub peers/peerjs-server: Server for PeerJS - GitHub PeerJS - Simple peer-to-peer with WebRTC A problem is I don't know how to integrate to the Nest.js project. I couldn't find examples. So I don't choose at least this time. What shall I choose? According MDN, WebRTC doesn't specify strictly what technology is used on server application for connecting two devices. Signaling and video calling - Web APIs | MDN But in many examples include MDN's one use WebSocket. samples-server/s/webrtc-from-chat at master · mdn/samples-server · GitHub So I try WebSocket in the Nest.js project. Use WebSocket in a Nest.js project Nest.js has a function for using We

[Nest.js] Show static files

Intro I wanted to use Nest.js and WebRTC(node-webrtc). NestJS - A progressive Node.js framework Documentation | NestJS - A progressive Node.js framework And because I wanted to try with simple page(not use JavaScript frameworks), I added static HTML, CSS, JavaScript into a Nest.js project. Prepare Install First, I installed @nestjs/cli. First steps | NestJS - A progressive Node.js framework As same as last time , I couldn't do global install because I had used Volta. But I could installed by volta. volta install @nestjs/cli Create project nest new nest-web-rtc-sample volta pin node@12 Run npm start After doing "npm start", I could getting "Hello World!" from http://localhost:3000. Add static files I could add static files by two ways. @nestjs/serve-static First one of them was using "serve-static". Serve Static | NestJS - A progressive Node.js framework npm install --save @nestjs/serve-static And I needed adding a module into app.modu