Tsed: Error when injecting one service in constructor another service

Created on 13 Jun 2019  路  4Comments  路  Source: tsedio/tsed

Information

  • Version: 5.x
  • Type: Issue/Story

Description

Error when injecting one service in constructor another service. Also i tried use InjectorService for it, but receive the same error.

Example

import { AfterRoutesInit, InjectorService, Service } from '@tsed/common';
import { TypeORMService } from '@tsed/typeorm';

@Service()
export class FirstService implements AfterRoutesInit {
  private connection: Connection;

  constructor(private typeORMService: TypeORMService, private secondService: SecondService) {}

  $afterRoutesInit() {
    this.connection = this.typeORMService.get(config.database.typeormName);
  }
}

@Service()
export class SecondService implements AfterRoutesInit {
  private connection: Connection;

  constructor(private typeORMService: TypeORMService) {}

  $afterRoutesInit() {
    this.connection = this.typeORMService.get(config.database.typeormName);
  }
}

Log

{ INJECTION_ERROR: Injection failed on ServiceCredentialService
    at Map._invoke (/Users/ivliev-andrey/Work/selhoz-bot/applications/backend/node_modules/@tsed/di/src/services/InjectorService.ts:409:13)
    at Map.invoke (/Users/ivliev-andrey/Work/selhoz-bot/applications/backend/node_modules/@tsed/di/src/services/InjectorService.ts:172:50)
    at Map.<anonymous> (/Users/ivliev-andrey/Work/selhoz-bot/applications/backend/node_modules/@tsed/di/src/services/InjectorService.ts:212:14)
    at Generator.next (<anonymous>)
    at /Users/ivliev-andrey/Work/selhoz-bot/applications/backend/node_modules/tslib/tslib.js:107:75
    at new Promise (<anonymous>)
    at Object.__awaiter (/Users/ivliev-andrey/Work/selhoz-bot/applications/backend/node_modules/tslib/tslib.js:103:16)
    at Map.load (/Users/ivliev-andrey/Work/selhoz-bot/applications/backend/node_modules/@tsed/di/lib/services/InjectorService.js:158:24)
    at Server.<anonymous> (/Users/ivliev-andrey/Work/selhoz-bot/applications/backend/node_modules/@tsed/common/src/server/components/ServerLoader.ts:440:25)
    at Generator.next (<anonymous>)
  name: 'INJECTION_ERROR',
  tokens: [ [Function: ServiceCredentialService] ] }

Maybe I misunderstand the concept DI, could not solve this problem

Most helpful comment

Problem solved, in tsconfig property emitDecoratorMetadata is set in true. I changed the re-export order in services/index.ts and all works fine. Thx!

All 4 comments

@revich2 What your Ts.ED version, exactly ? Because, the latest version display more information when injection failed. Injection could be failed because you have a javascript error in your ServiceCredentialService constructor and ts.ed version under 5.18 didn't display the complete error in this case. Can you update the ts.ed version and tell me if your trace error shown more information ?

For me your given example is correct ^^

See you
Romain

@Romakita Updated to version 5.19.0, really more information about the error, but what's the problem, still do not understand.

New log

{ INJECTION_ERROR: Injection failed on ServiceCredentialService
Origin: 
    at Map._invoke (/Users/ivliev-andrey/Work/selhoz-bot/applications/backend/node_modules/@tsed/di/src/services/InjectorService.ts:431:13)
    at Map.invoke (/Users/ivliev-andrey/Work/selhoz-bot/applications/backend/node_modules/@tsed/di/src/services/InjectorService.ts:173:50)
    at Map.<anonymous> (/Users/ivliev-andrey/Work/selhoz-bot/applications/backend/node_modules/@tsed/di/src/services/InjectorService.ts:213:14)
    at Generator.next (<anonymous>)
    at /Users/ivliev-andrey/Work/selhoz-bot/applications/backend/node_modules/tslib/tslib.js:110:75
    at new Promise (<anonymous>)
    at Object.__awaiter (/Users/ivliev-andrey/Work/selhoz-bot/applications/backend/node_modules/tslib/tslib.js:106:16)
    at Map.load (/Users/ivliev-andrey/Work/selhoz-bot/applications/backend/node_modules/@tsed/di/lib/services/InjectorService.js:159:24)
    at Server.<anonymous> (/Users/ivliev-andrey/Work/selhoz-bot/applications/backend/node_modules/@tsed/common/src/server/components/ServerLoader.ts:440:25)
    at Generator.next (<anonymous>)
  name: 'INJECTION_ERROR',
  tokens: [ [Function: ServiceCredentialService] ],
  origin:
   TypeError: 
       at Object.getMetadata (/Users/ivliev-andrey/Work/selhoz-bot/applications/backend/node_modules/reflect-metadata/Reflect.js:354:23)
       at Function.getParamTypes (/Users/ivliev-andrey/Work/selhoz-bot/applications/backend/node_modules/@tsed/core/src/class/Metadata.ts:462:20)
       at Map.mapInvokeOptions (/Users/ivliev-andrey/Work/selhoz-bot/applications/backend/node_modules/@tsed/di/src/services/InjectorService.ts:476:31)
       at Map._invoke (/Users/ivliev-andrey/Work/selhoz-bot/applications/backend/node_modules/@tsed/di/src/services/InjectorService.ts:406:55)
       at Map.invoke (/Users/ivliev-andrey/Work/selhoz-bot/applications/backend/node_modules/@tsed/di/src/services/InjectorService.ts:168:35)
       at Map._invoke (/Users/ivliev-andrey/Work/selhoz-bot/applications/backend/node_modules/@tsed/di/src/services/InjectorService.ts:425:42)
       at Map.invoke (/Users/ivliev-andrey/Work/selhoz-bot/applications/backend/node_modules/@tsed/di/src/services/InjectorService.ts:173:50)
       at Map.<anonymous> (/Users/ivliev-andrey/Work/selhoz-bot/applications/backend/node_modules/@tsed/di/src/services/InjectorService.ts:213:14)
       at Generator.next (<anonymous>)
       at /Users/ivliev-andrey/Work/selhoz-bot/applications/backend/node_modules/tslib/tslib.js:110:75 }

Ok. Can you send me your tsconfig.json please ?

getMetadata error means (generally), the tsconfig is misconfigured and emitDecoratorMetadata isn't set to true.

According to your example, you have to switch the class declaration order.

import { AfterRoutesInit, InjectorService, Service } from '@tsed/common';
import { TypeORMService } from '@tsed/typeorm';

@Service()
export class SecondService implements AfterRoutesInit {
  private connection: Connection;

  constructor(private typeORMService: TypeORMService) {}

  $afterRoutesInit() {
    this.connection = this.typeORMService.get(config.database.typeormName);
  }
}

@Service()
export class FirstService implements AfterRoutesInit {
  private connection: Connection;

  constructor(private typeORMService: TypeORMService, private secondService: SecondService) {}

  $afterRoutesInit() {
    this.connection = this.typeORMService.get(config.database.typeormName);
  }
}

See you,

Problem solved, in tsconfig property emitDecoratorMetadata is set in true. I changed the re-export order in services/index.ts and all works fine. Thx!

Was this page helpful?
0 / 5 - 0 ratings