Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Must there provide a name for @Service and @Inject? #4

Closed
Diluka opened this issue Aug 4, 2016 · 12 comments
Closed

Must there provide a name for @Service and @Inject? #4

Diluka opened this issue Aug 4, 2016 · 12 comments

Comments

@Diluka
Copy link

Diluka commented Aug 4, 2016

I use empty @Service() and @Inject(), so raise an error TypeError: Cannot read property 'bind' of undefined

I add a name to both then they work fine.

typedi 0.4.2
node 6.2.1

@pleerock
Copy link
Contributor

pleerock commented Aug 4, 2016

can you provide a code sample?

@Diluka
Copy link
Author

Diluka commented Aug 8, 2016

todo.controller.ts

import {Get, Post, UseInterceptor, Body, Controller} from "routing-controllers";
import {TodoService} from "../service/todo.service";
import {Inject} from "typedi";
import * as _ from "lodash";
import * as AV from "leanengine";

@Controller("/todos")
export class TodoController {

    @Inject() private todoService:TodoService;


    @Get("/")
    @UseInterceptor((req, res, content) => {
        if (_.isArray(content)) {
            return _.map(content, (o:AV.Object) => o.toJSON());
        }
        return content;
    })
    getAll() {
        return this.todoService.getAll();
    }

    // @Post("/")
    // post(@Body() data) {
    //     return this.todoService.save(data);
    // }
}

todo.service.ts

import * as AV from "leanengine";
import {Service} from "typedi";
import {Todo} from "../entity";


@Service()
export class TodoService {
    getAll() {
        return new AV.Query(Todo).find<AV.Object[]>();
    }

    save(data) {
        return new Todo(data).save<AV.Object>();
    }
}

app.ts

import "reflect-metadata";
import {createExpressServer, useContainer} from "routing-controllers";
import {Container} from "typedi";
import * as Express from "express";
import * as AV from "leanengine";

// load all services
import "./service";

useContainer(Container);

export const app: Express.Application = createExpressServer({
    controllerDirs: [__dirname + "/controller/*.controller.js"]
});

app.use(AV.express());

error stack

TypeError: Cannot read property 'bind' of undefined                                                                                                                                                
    at Function.Container.get (D:\Users\Diluka\Documents\GitHub\leancloud-demo\node_modules\.npminstall\typedi\0.4.2\typedi\Container.js:64:39)                                                    
    at Object.Container_1.Container.registerPropertyHandler.getValue (D:\Users\Diluka\Documents\GitHub\leancloud-demo\node_modules\.npminstall\typedi\0.4.2\typedi\decorators.js:31:70)            
    at D:\Users\Diluka\Documents\GitHub\leancloud-demo\node_modules\.npminstall\typedi\0.4.2\typedi\Container.js:110:40                                                                            
    at Array.forEach (native)                                                                                                                                                                      
    at Function.Container.applyPropertyHandlers (D:\Users\Diluka\Documents\GitHub\leancloud-demo\node_modules\.npminstall\typedi\0.4.2\typedi\Container.js:105:14)                                 
    at Function.Container.get (D:\Users\Diluka\Documents\GitHub\leancloud-demo\node_modules\.npminstall\typedi\0.4.2\typedi\Container.js:66:14)                                                    
    at Object.getFromContainer (D:\Users\Diluka\Documents\GitHub\leancloud-demo\node_modules\.npminstall\routing-controllers\0.6.2\routing-controllers\container.js:36:42)                         
    at ControllerMetadata.Object.defineProperty.get [as instance] (D:\Users\Diluka\Documents\GitHub\leancloud-demo\node_modules\.npminstall\routing-controllers\0.6.2\routing-controllers\metadata\
ControllerMetadata.js:27:32)                                                                                                                                                                       
    at ActionMetadata.executeAction (D:\Users\Diluka\Documents\GitHub\leancloud-demo\node_modules\.npminstall\routing-controllers\0.6.2\routing-controllers\metadata\ActionMetadata.js:258:39)     
    at D:\Users\Diluka\Documents\GitHub\leancloud-demo\node_modules\.npminstall\routing-controllers\0.6.2\routing-controllers\RoutingControllerExecutor.js:74:33                                      

@Diluka
Copy link
Author

Diluka commented Aug 8, 2016

@pleerock
Copy link
Contributor

pleerock commented Aug 9, 2016

@Diluka how to reproduce this error in your demo? Im running node ./dist/app.js and have no issue (p.s. i added ("emitDecoratorMetadata": true and "experimentalDecorators": true) to your tsconfig.json)

@Diluka
Copy link
Author

Diluka commented Aug 9, 2016

thanks a lot

the same with typestack/routing-controllers#16

closing

@Diluka Diluka closed this as completed Aug 9, 2016
@mogusbi
Copy link

mogusbi commented Jul 12, 2017

@pleerock Sorry for commenting on a closed issue, but I'm also having this exact issue - example repo here: https://github.com/mogusbi/typedi-error

Whenever I hit my routing-controller endpoint, I'm met with this error

{
    "name": "TypeError",
    "message": "Cannot read property 'readAll' of undefined",
    "stack": "TypeError: Cannot read property 'readAll' of undefined\n    at QuestionController.httpGetAll (/Volumes/Data/Users/mo/Desktop/typeorm/src/controllers/question/question.controller.ts:11:32)\n    at ActionMetadata.callMethod (/Volumes/Data/Users/mo/Desktop/typeorm/src/metadata/ActionMetadata.ts:254:62)\n    at /Volumes/Data/Users/mo/Desktop/typeorm/src/RoutingControllers.ts:123:142"
}

Here's a quick recap of my code

// question.controller.ts

import {Body, Delete, Get, HttpCode, JsonController, Param, Post, Put} from 'routing-controllers';
import {Inject} from 'typedi';
import {IQuestion, Question, QuestionService} from '../../entities/question';

@JsonController('/question')
export class QuestionController {
  @Inject() private questionService: QuestionService;

  @Get()
  public httpGetAll (): Promise<[Question[], number]> {
    return this.questionService.readAll();
  }

  @Get('/:id')
  public httpGetOne (
    @Param('id') id: string
  ): Promise<Question> {
    return this.questionService.readOne(id);
  }

  @Post()
  @HttpCode(201)
  public httpPost (
    @Body({
      required: true
    }) props: IQuestion
  ): Promise<Question> {
    return this.questionService.create(props);
  }

  @Put('/:id')
  public httpPut (
    @Param('id') id: string,
    @Body({
      required: true
    }) props: IQuestion
  ): Promise<void> {
    return this.questionService.update(id, props);
  }

  @Delete('/:id')
  public httpDelete (
    @Param('id') id: string
  ): Promise<void> {
    return this.questionService.drop(id);
  }
}
// question.service.ts

import {Service} from 'typedi';
import {Repository} from 'typeorm';
import {OrmRepository} from 'typeorm-typedi-extensions';
import {IQuestion} from './question.interface';
import {Question} from './question.model';

@Service()
export class QuestionService {
  @OrmRepository(Question) private repository: Repository<Question>;

  public create (props: IQuestion): Promise<Question> {
    return this.repository.persist(props);
  }

  public readAll (size: number = 10, page: number = 1): Promise<[Question[], number]> {
    const skip: number = size * (page - 1);

    return this.repository.findAndCount({
      skip,
      take: page
    });
  }

  public readOne (id: string): Promise<Question> {
    return this.repository.findOneById(id);
  }

  public update (id: string, props: IQuestion): Promise<void> {
    return this.repository.updateById(id, props);
  }

  public drop (id: string): Promise<void> {
    return this.repository.removeById(id);
  }
}
// www.ts

import * as http from 'http';
import 'reflect-metadata';
import {Container} from 'typedi';
import {createConnection, useContainer} from 'typeorm';
import {config} from '../config';
import {BaseEntity, Question} from '../entities';
import {app} from './app';

useContainer(Container);

createConnection({
  ...config.sql,
  entities: [
    BaseEntity,
    Question
  ]
}).then(
  () => http
    .createServer(app)
    .listen(8082, () => console.log('Server started on port 8082'))
).catch(
  (err: Error) => console.error(err.message)
);
// tsconfig.json

{
  "compilerOptions": {
    "declaration": false,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "importHelpers": true,
    "lib": [
      "es2015",
      "es2016"
    ],
    "module": "commonjs",
    "moduleResolution": "node",
    "noEmitHelpers": true,
    "noImplicitAny": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "removeComments": true,
    "skipLibCheck": true,
    "sourceMap": true,
    "suppressImplicitAnyIndexErrors": true,
    "target": "es5"
  },
  "awesomeTypescriptLoaderOptions": {
    "useWebpackText": true
  }
}

I am running typescript 2.4.1 and node 6.10.2

@gjdass
Copy link
Contributor

gjdass commented Jul 14, 2017

@mogusbi Hey, found out by looking at the @Diluka bug report code.

You certainly forgot :

import { Container } from "typedi";
import { useContainer } from 'routing-controllers';

useContainer(Container);

To place into your app.ts. It tells to routing-controllers to use the container from typeDI.

See this file.

@pleerock maybe it should appear somewhere in a "Troubleshooting" section or whatever ? I know this is related to routing-controller or whatever lib we use in complement of TypeDI, but I think a great number of developers may face this at some point. Idk, what you think ?

@mogusbi
Copy link

mogusbi commented Jul 14, 2017

@gjdass perfect, that's working now. Thank you very much!

@pleerock
Copy link
Contributor

yeah we can add links in Troubleshooting section, like this:

Troubleshooting

  • how to use TypeDI with TypeORM
  • how to use TypeDI with routing-controllers
    ...

with links to appropriate qa. PRs are welcomed

@gjdass
Copy link
Contributor

gjdass commented Jul 15, 2017

@pleerock done ;) #32

@pleerock
Copy link
Contributor

Thank you!

@github-actions
Copy link

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.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 31, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

No branches or pull requests

4 participants