nestjs / nest

A progressive Node.js framework for building efficient, scalable, and enterprise-grade server-side applications with TypeScript/JavaScript 🚀
https://nestjs.com
MIT License
66.9k stars 7.55k forks source link

TypeOrmModule causes controller params to be undefined #13297

Closed moshicohen closed 6 months ago

moshicohen commented 6 months ago

Is there an existing issue for this?

Current behavior

Hi In this very simple example, you'll see a well working controller with 1 param, and when we add TypeOrmModule on the app.module, the param gets with undefined value. app.controller:

@Controller('app')
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get('/:id')
  getHello(@Param('id') id: string): string {
    console.log(id);
    return this.appService.getHello();
  }
}

app.module:

@Module({
  imports: [
    UsersModule,
    ScheduleModule.forRoot(),
    CacheModule.register({ isGlobal: true }),
    HttpModule,
    ConfigModule.forRoot({
      isGlobal: true,
      envFilePath: ['.env.dev'],
    }),
    TypeOrmModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: async (configService: ConfigService) => ({
        type: 'postgres',
        autoLoadEntities: true,
        synchronize: true,
        host: configService.get('DB_HOST'),
        port: configService.get('DB_PORT'),
        username: configService.get('DB_USERNAME'),
        password: configService.get('DB_PASSWORD'),
        database: configService.get('DB_DATABASE'),
      }),
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

In order to test, I run: localhost:3000/app/1

Please note that if I remove the TypeOrmModule code from app.module, it is working fine!

Thanks!

Minimum reproduction code

https://stackblitz.com/edit/nestjs-typescript-starter-p64pxj?file=.env.dev,src%2Fapp.module.ts&terminal=start

Steps to reproduce

No response

Expected behavior

I would expect to see ,on debug, the controller 'id' param appears with '1' value and not undefined.

Package

Other package

typeorm @nestjs/typeorm

NestJS version

10.0.0

Packages versions

"dependencies": {
    "@nestjs/axios": "^3.0.1",
    "@nestjs/cache-manager": "^2.2.0",
    "@nestjs/common": "^10.0.0",
    "@nestjs/config": "^3.1.1",
    "@nestjs/core": "^10.0.0",
    "@nestjs/platform-express": "^10.0.0",
    "@nestjs/schedule": "^4.0.0",
    "@nestjs/typeorm": "^10.0.2",
    "axios": "^1.6.5",
    "cache-manager": "^5.3.2",
    "class-transformer": "^0.5.1",
    "class-validator": "^0.14.0",
    "concurrently": "^8.2.2",
    "cors": "^2.8.5",
    "cpx": "^1.5.0",
    "pg": "^8.11.3",
    "reflect-metadata": "^0.1.13",
    "rxjs": "^7.8.1",
    "typeorm": "^0.3.20",
    "winston": "^3.11.0"
  },
  "devDependencies": {
    "@nestjs/cli": "^10.0.0",
    "@nestjs/mapped-types": "^2.0.4",
    "@nestjs/schematics": "^10.0.0",
    "@nestjs/testing": "^10.0.0",
    "@types/babel__core": "^7.20.5",
    "@types/express": "^4.17.17",
    "@types/jest": "^29.5.2",
    "@types/node": "^20.3.1",
    "@types/supertest": "^2.0.12",
    "@typescript-eslint/eslint-plugin": "^6.0.0",
    "@typescript-eslint/parser": "^6.0.0",
    "eslint": "^8.42.0",
    "eslint-config-prettier": "^9.1.0",
    "eslint-plugin-prettier": "^5.1.2",
    "jest": "^29.5.0",
    "prettier": "^3.1.1",
    "source-map-support": "^0.5.21",
    "supertest": "^6.3.3",
    "ts-jest": "^29.1.0",
    "ts-loader": "^9.4.3",
    "ts-node": "^10.9.1",
    "tsconfig-paths": "^4.2.0",
    "typescript": "^5.1.3"
  },

Node.js version

18.13.0

In which operating systems have you tested?

Other

Please note that you won't be able to use the Stackblitz as is because it can't connect to DB. I'm using a PG DB on my local, so the credentials should be changed in the .env.dev file. Thanks.

kamilmysliwiec commented 6 months ago

https://github.com/nestjs/nest/issues/13146

TLDR; make sure you use the latest version (so the reflect-metadata version is in sync)

moshicohen commented 6 months ago

Thanks, I have ran: npx npm-check-updates -u but I still have the same problem. Here are my updated dependencies:

"dependencies": {
    "@nestjs/common": "^10.3.3",
    "@nestjs/config": "^3.2.0",
    "@nestjs/core": "^10.3.3",
    "@nestjs/platform-express": "^10.3.3",
    "@nestjs/typeorm": "^10.0.2",
    "class-transformer": "^0.5.1",
    "class-validator": "^0.14.1",
    "pg": "^8.11.3",
    "reflect-metadata": "^0.2.1",
    "rxjs": "^7.8.1",
    "typeorm": "^0.3.20",
    "uuid": "^9.0.1",
    "winston": "^3.12.0"
  },
  "devDependencies": {
    "@nestjs/cli": "^10.3.2",
    "@nestjs/schematics": "^10.1.1",
    "@nestjs/testing": "^10.3.3",
    "@types/express": "^4.17.21",
    "@types/jest": "^29.5.12",
    "@types/node": "^20.11.24",
    "@types/supertest": "^6.0.2",
    "@types/uuid": "^9.0.8",
    "@typescript-eslint/eslint-plugin": "^7.1.1",
    "@typescript-eslint/parser": "^7.1.1",
    "eslint": "^8.57.0",
    "eslint-config-prettier": "^9.1.0",
    "eslint-plugin-prettier": "^5.1.3",
    "jest": "^29.7.0",
    "prettier": "^3.2.5",
    "source-map-support": "^0.5.21",
    "supertest": "^6.3.4",
    "ts-jest": "^29.1.2",
    "ts-loader": "^9.5.1",
    "ts-node": "^10.9.2",
    "tsconfig-paths": "^4.2.0",
    "typescript": "^5.3.3"
  },
kamilmysliwiec commented 6 months ago

Please, provide a minimum reproduction repository.

You can also try removing the lock file & node_modules folder and re-running npm install

moshicohen commented 6 months ago

So I have tried to provide a reproduction on Stackblitz, the problem is that it can't connect to DB so it throws an error an won't run. I can add once again my very basic app.controller and app.module. regarding the deletion of node modules and re-run npm i - I have already done it and it didn't solve. Thanks for your efforts !

my app.controller:


@Controller('app')
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get('/:id')
  getHello(@Param('id') id: string): string {
    console.log(id);
    return this.appService.getHello();
  }
}

my app.module:


@Module({
  imports: [
    UsersModule,
    ScheduleModule.forRoot(),
    CacheModule.register({ isGlobal: true }),
    HttpModule,
    ConfigModule.forRoot({
      isGlobal: true,
      envFilePath: ['.env.dev'],
    }),
    TypeOrmModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: async (configService: ConfigService) => ({
        type: 'postgres',
        autoLoadEntities: true,
        synchronize: true,
        host: configService.get('DB_HOST'),
        port: configService.get('DB_PORT'),
        username: configService.get('DB_USERNAME'),
        password: configService.get('DB_PASSWORD'),
        database: configService.get('DB_DATABASE'),
      }),
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
phuffer commented 6 months ago

For me @kamilmysliwiec's suggestion worked.

@moshicohen I updated my project to use all the dependencies you listed and my controller's still worked. Maybe inspect your package-lock.json and ensure the correct reflect-metadata version is being used and something else isn't pulling in 0.1.12.

moshicohen commented 6 months ago

You are right guys, it was finally the version pf reflect-metadata. When I ran: npx npm-check-updates -u it didn't update it. I had to manually: npm install reflect-metadata@^0.2 and it solved it. Thanks !

alper commented 6 months ago

I banged my head against the wall for an hour trying to figure out why everything was coming in undefined.

This is extremely cursed/broken behaviour and impossible to debug on the server itself.

kamilmysliwiec commented 6 months ago

I belive that typeorm maintainers could easily fix this issue if they followed this comment https://github.com/typeorm/typeorm/issues/10671#issuecomment-1931628948