typestack / typeorm-typedi-extensions

Dependency injection and service container integration with TypeORM using TypeDI library.
MIT License
262 stars 37 forks source link

injected repository is always undefined #25

Closed babakyakhchali closed 3 years ago

babakyakhchali commented 6 years ago

Hi I'm trying to inject some repository into a routing-controllers controller like this:

import { Param, Body, Get, Post, Put, Delete, JsonController } from "routing-controllers";
import { InjectRepository } from "typeorm-typedi-extensions";
import { Repository } from "typeorm";
import { User } from "../entities/User";
import { Service } from "typedi";

@JsonController('/users')
@Service()
export class UserController {

    @InjectRepository(User)
    private repository: Repository<User>;

    @Get("/")
    getAll() {
        return this.repository.find();
    }
}

but this.repository is always undefined!

this is my app entry main.ts file:

import "reflect-metadata";
import { createConnection, useContainer} from 'typeorm';
import { createExpressServer } from "routing-controllers";
import { UserController } from "./src/controllers/UserController";

import { Container } from 'typedi';

useContainer(Container);
createConnection().then(async connection => {
}).catch(error => console.log(error));

const app = createExpressServer({
    controllers: [UserController] // we specify controllers we want to use
 });
 app.listen(3000);

all entities are created and express is working.

ReganHe commented 6 years ago

InjectRepository被重命名了,改用OrmRepository。 参考:https://github.com/typeorm/typeorm-typedi-extensions/commit/1002d8e07879fb63ad4efcd5b483f544fa9dc15b

nodew commented 6 years ago

the same issue as @babakyakhchali

lenmerkel commented 6 years ago

I have a very similar setup to @babakyakhchali and see exactly the same behavior. I can step into useContainer and @InjectRepository, both appear to execute normally (i.e. no Errors thrown). However, the property is never initialized (i.e. it is undefined).

My npm dependencies and installed packages are:

  "devDependencies": {
    "@types/node": "^10.11.6",
    "ts-node": "^7.0.1",
    "typescript": "^3.1.1"
  },
  "dependencies": {
    "class-transformer": "^0.1.9",
    "graphql-yoga": "^1.16.2",
    "mysql": "^2.16.0",
    "reflect-metadata": "^0.1.12",
    "type-graphql": "^0.14.0",
    "typedi": "^0.8.0",
    "typeorm": "^0.2.7",
    "typeorm-typedi-extensions": "^0.2.1"
  }
feimosi commented 5 years ago

Doesn't work for me either (I've tried InjectManager and InjectRepository).

nikomon commented 5 years ago

Same issue

alexeychikk commented 5 years ago

@babakyakhchali @nodew @feimosi @nikomon Guys, has someone managed to find the source of the issue?

feimosi commented 5 years ago

I don't already remember, it's been a very long time ago. I have the latest version of each package and everything works fine. Maybe make sure you invoke useContainer from both packages separately (typeorm and routing-controllers).

alexeychikk commented 5 years ago

@feimosi I found the source of the issue. I am trying to inject repository into repository. And for some reason this is not working. When I try to inject the same repository into service - it does work.

peterbabic commented 5 years ago

For me, using type-grapghql the difference was in

const schema = await buildSchema({
    resolvers: [UserResolver],
    // need to register the container here as well
    container: Container
})

just using useContainer(Container) from typeorm is not enough

Tecnology73 commented 5 years ago

As @peterbabic suggested, I also had to do something like this;

private async buildSchema() {
    useContainer(Container);

    return await buildSchema({
        resolvers: [ UserResolver ],
        emitSchemaFile: true,
        container: Container,
    });
}
nbaua commented 5 years ago

I have following code (some lines removed for brevity)

` @Injectable() export class ProductsService { constructor( @InjectRepository(ProductRepository) private repo: ProductRepository, ) { console.log('inside service'); } ...... ....... async getProductById(id: number): Promise { console.log(this.repo);

const matchingProduct = await this.repo.findOne(id);
if (!matchingProduct) {
  throw new NotFoundException(`Product Not Found!`);
}
return matchingProduct;

} } `

I get the following error at run-time. There are no compile-time issues, server starts/runs perfectly fine, until we hit the end-point because ProductRepository is always undefined.

[Nest] 4708 - 07/27/2019, 9:40 PM [ExceptionsHandler] Cannot read property 'findOne' of undefined +205ms TypeError: Cannot read property 'findOne' of undefined at ProductRepository.Repository.findOne (D:\Projects\BestDealsOnline\src\repository\Repository.ts:296:29) at ProductsService.getProductById (D:\Projects\BestDealsOnline\src\products\products.service.ts:35:45) at ProductsController.getProductById (D:\Projects\BestDealsOnline\src\products\products.controller.ts:34:33)

This code was working days before. Please suggest how this can be resolved.

shahzaib-sheikh commented 4 years ago

I was facing the same issue. It turned out to be a circular dependency issue.

arslanmughal99 commented 4 years ago

I was facing the same issue. It turned out to be a circular dependency issue.

Can you please show example how you fix that ? i'm also facing same issue as @nbaua i have also tried forwardRef but no luck :-(

shahzaib-sheikh commented 4 years ago

I just removed the code which was causing circular dependency. To check for circular dependency start with the class which is returned undefined from Typedi, In that class check for files which this file imports. you will get to the code which is causing circular dependency. Also setup debugger if you haven't and put a breakpoint on the class which is undefined. when the code stops at breakpoint look into the stack trace you'll definitely get to that code.

arslanmughal99 commented 4 years ago

So my solution was to replace this

export class UserService {
    constructor(
         @InjectRepository(UserRepository)
         private userRepository: UserRepository;

         @InjectRepository(AuthRepository)
         private authRepository: AuthRepository;
     ) {  }
}

with this using Connection from typeorm

export class UserService {
    private userRepository: UserRepository;
    private authRepository: AuthRepository;
    constructor(
        private readonly connection: Connection
    ) {
        this.userRepository = this.connection.getCustomRepository(UserRepository);
        this.authRepository = this.connection.getCustomRepository(AuthRepository);
    }
}

Now it work like charm :)

theoparis commented 4 years ago

same issue, i tried injectconnection AND injectrepository but both didnt work and the repo is undefined.

arslanmughal99 commented 4 years ago

@creepinson can you show your code where it is undefined ?

JipSterk commented 3 years ago

i use a resolver from type-graphql which import code like the snippet below when the object instantiated by type-di with a inject.

@Inject(() => UserService)

when kafka consumer has called his eachMessage. userRepository hasn't been instantiated yet

@Service()
export class UserService {
  @InjectRepository(User)
  private readonly userRepository: Repository<User>;

  constructor() {
    this.setupUserConsumer();
  }

  async setupUserConsumer(): Promise<void> {
    const userConsumer = kafka.consumer({ groupId: "user-group" });
    await userConsumer.connect();
    await userConsumer.subscribe({
      topic: "create-user",
      fromBeginning: true,
    });
    await userConsumer.run({
      eachMessage: this.createUser,
    });
  }

  private async createUser({ message }: EachMessagePayload): Promise<void> {
    const { user } = JSON.parse(
      message.value.toString()
    ) as CreateUserMessage;

    await this.userRepository.save({ //<-- here userRepository is undefined 
      id: user.id,
    });
  }
}
NoNameProvided commented 3 years ago

There are tons of unrelated issues here. I am closing this, if you are still facing issues, please open a new issue with a minimal, reproducible example. Thanks!

github-actions[bot] commented 3 years ago

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.