nestjsnestjs-confignestjs-typeorm

Nestjs with TypeORM - Cannot read properties of undefined / No metadata was found - server starts all routes without error at startup


I am currently trying to build a simple Nestjs Api (Nestjs v9, TypeORM v9, postgres:14-alpine). The application has no logic yet, but already has some routes, as you can see from the output:

[12:28:58 AM] Found 0 errors. Watching for file changes.

[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [NestFactory] Starting Nest application...
[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [InstanceLoader] TypeOrmModule dependencies initialized +28ms
[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [InstanceLoader] PassportModule dependencies initialized +0ms
[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [InstanceLoader] JwtModule dependencies initialized +0ms
[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [InstanceLoader] JwtModule dependencies initialized +0ms
[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [InstanceLoader] AppModule dependencies initialized +0ms
[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [InstanceLoader] UsersModule dependencies initialized +0ms
[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [InstanceLoader] TypeOrmCoreModule dependencies initialized +61ms
[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [InstanceLoader] TypeOrmModule dependencies initialized +1ms
[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [InstanceLoader] TypeOrmModule dependencies initialized +0ms
[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [InstanceLoader] QuestionsModule dependencies initialized +7ms
[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [InstanceLoader] AuthModule dependencies initialized +0ms
[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [RoutesResolver] AppController {/}: +7ms
[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [RouterExplorer] Mapped {/, GET} route +1ms
[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [RoutesResolver] AuthController {/auth}: +0ms
[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [RouterExplorer] Mapped {/auth/signup, POST} route +1ms
[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [RouterExplorer] Mapped {/auth/signin, POST} route +0ms
[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [RouterExplorer] Mapped {/auth/test, POST} route +0ms
[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [RoutesResolver] UserController {/users}: +1ms
[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [RouterExplorer] Mapped {/users, POST} route +0ms
[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [RouterExplorer] Mapped {/users/login, POST} route +1ms
[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [RouterExplorer] Mapped {/users, GET} route +0ms
[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [RoutesResolver] QuestionsController {/questions}: +0ms
[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [RouterExplorer] Mapped {/questions, POST} route +0ms
[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [RouterExplorer] Mapped {/questions, GET} route +1ms
[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [RouterExplorer] Mapped {/questions/:id, GET} route +0ms
[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [RouterExplorer] Mapped {/questions/:id, PUT} route +0ms
[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [RouterExplorer] Mapped {/questions/:id, DELETE} route +1ms
[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [RouterExplorer] Mapped {/questions/:id/markAsRead, POST} route +0ms
[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [RouterExplorer] Mapped {/questions/unread, GET} route +0ms
[Nest] 22189  - 05/19/2023, 12:28:59 AM     LOG [NestApplication] Nest application successfully started +2ms

Also, the connection to Postgres (Docker image) works and three tables are automatically created at startup.

However, as soon as I send a post request via Postman to http://localhost:3000/users with the following JSON object in the body (PS: Get Request does not work either):

{
    "username": "testUser",
    "password": "testPassword"
}

I receive from Postman :

{ "statusCode": 500, "message": "Internal server error" }

And in the Nestjs an error:

ERROR [ExceptionsHandler] Cannot read properties of undefined (reading 'create') TypeError: Cannot read properties of undefined (reading 'create') at UserRepository.create at UsersService.createUser at UserController.createUser

Here is my code:

Controller:

// src/users/users.controller.ts

import { Controller, Get, Post, Body } from '@nestjs/common';
import { UsersService } from './users.service';
import { AuthService } from '../auth/auth.service';
import { CreateUserDto } from './dto/create-user.dto';
import { AuthCredentialsDto } from '../auth/dto/auth-credentials.dto';

@Controller('users')
export class UserController {
  constructor(
    private readonly usersService: UsersService,
    private readonly authService: AuthService,
  ) {}

  @Post()
  async createUser(@Body() createUserDto: CreateUserDto) {
    return this.usersService.createUser(createUserDto);
  }

  // more code
}

Service:

// src/users/users.service.ts

import { Injectable } from '@nestjs/common';
import { UserRepository } from './user.repository';
import { InjectRepository } from '@nestjs/typeorm';
import { CreateUserDto } from './dto/create-user.dto';

@Injectable()
export class UsersService {
  constructor(
    @InjectRepository(UserRepository)
    private userRepository: UserRepository,
  ) {}

  async createUser(createUserDto: CreateUserDto) {
    const user = this.userRepository.create(createUserDto);
    await this.userRepository.save(user);
    return user;
  }

  // more code
}

Module:

// src/users/users.module.ts

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';
import { UserRepository } from './user.repository';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { UserController } from './users.controller';
import { AuthService } from '../auth/auth.service';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  controllers: [UserController],
  imports: [
    TypeOrmModule.forFeature([UserRepository]),
    JwtModule.register({}),
    PassportModule.register({ defaultStrategy: 'jwt' }),
  ],
  providers: [UsersService, UserRepository, AuthService],
})
export class UsersModule {}

TypeORM is configured in my app.module and the connection is working:

// src/app.module.ts

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { AuthModule } from './auth/auth.module';
import { UsersModule } from './users/users.module';
import { QuestionsModule } from './questions/questions.module';
import { UserEntity } from './users/user.entity';
import { QuestionEntity } from './questions/question.entity';
import { UserQuestionEntity } from './questions/user-question.entity';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'postgres',
      host: 'localhost',
      port: 5432,
      username: 'test',
      password: 'test',
      database: 'test',
      entities: [UserEntity, QuestionEntity, UserQuestionEntity],
      synchronize: true,
    }),
    AuthModule,
    UsersModule,
    QuestionsModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

I don't understand what the issue is and how to fix it. Tell me if you want me to show you some other files.

Update:

User Repository:

// src/users/user.repository.ts

import { EntityRepository, Repository } from 'typeorm';
import { UserEntity } from './user.entity';

@EntityRepository(UserEntity)
export class UserRepository extends Repository<UserEntity> {}

User Entity:

// src/users/user.entity.ts

import { UserQuestionEntity } from 'src/questions/user-question.entity';
import { Entity, Column, PrimaryGeneratedColumn, OneToMany } from 'typeorm';

@Entity('users')
export class UserEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ unique: true })
  username: string;

  @Column()
  password: string;

  @OneToMany(() => UserQuestionEntity, (userQuestion) => userQuestion.user)
  userQuestions: UserQuestionEntity[];
}

Solution

  • the cause is here:

    private userRepository: UserRepository,
    

    you should put your entity here like this below:

    
        @InjectRepository(UserEntity)
        private userRepository: Repository<UserEntity>,