InversifyJS: property injection not working in React
I am writing learning React and I wanted to use it inversifyjs as I have been using it for other projects. I have seen that in order to use it with react we have to use inversify-inject-decorators and I have followed the guide for this package but I cannot get the injection working
Expected Behavior
IoC.ts
import { Container} from "inversify";
import getDecorators from "inversify-inject-decorators";
import { GameServices } from "../providers/game/game.services";
import { IGameService } from "../providers/game/game.service.interfaces";
const container = new Container();
container.bind<IGameService>("gameServices").toConstructor(GameServices);
const { lazyInject} = getDecorators(container);
export {lazyInject};
in GameServices
import { IGameService, IHistoryItem } from "./game.service.interfaces";
import { injectable } from "inversify";
@injectable()
export class GameServices implements IGameService {
private readonly statistics: IHistoryItem[] = [];
private moves: number = 0;
calculateWinner(squares: string[]): string {
//do something
return "";
}
public retrieveStatistics(): IHistoryItem[] {
return this.statistics;
}
}
Game Component
class Game extends React.Component<{}, GameState> {
@lazyInject("gameServices")
private readonly gameServices: IGameService;
public render() {
const history = this.state.history;
const current = history[this.state.stepNumber];
console.log("calling the service", this.gameServices)
const winner = this.gameServices.calculateWinner(current.squares);
return ();
}
}
This code should work
Current Behavior
I am not getting any compilation error but when the line
const winner = this.gameServices.calculateWinner(current.squares);
gets executed I get an exception because gameService is undefined…
Environment
- Version used:
- inversify": “^5.0.1”,
- “inversify-inject-decorators”: “^3.1.0”,
- “typescript”: “^3.2.2”
- “react”: “^16.7.0”,
About this issue
- Original URL
- State: open
- Created 5 years ago
- Reactions: 9
- Comments: 18 (2 by maintainers)
Just found this issue while trying to solve the same problem for project using babel with plugin-proposal-decorators (legacy mode). My workaround is to define own decorators which exploit babel’s internal
initializer
(can read about it here) descriptor property to settle down prototype lookup:Usage:
Any update on this? Workarounds actually not working for us…
Use a workaround to make the inject work.
In this week I started to learn about inversify with React too and I’m having the same issue… I got the basic example of https://github.com/inversify/inversify-inject-decorators and just pasted it on a new class in my project, just to test, and even the basic example was not working.
I was looking in the implementation, trying to find some guess of what was happening… This library (if I didnt get wrong) inject the properties on the prototype of the object, so the injection works only when you do a get on the property of prototype.
When you do a get on the object, the js will look at the instance to see if the property exists there. If it doesnt then Js will look at the instance’s prototype chain until get the value wanted.
The problem is that when you create a instance (new WhateverClass()) all properties will be in your instance, so js will never do a search on the prototype chain and, because of that, your instance will never be injected.
To exemplify what I’m talking about I got the basic example I said above and made some changes. That’s an example of what is happening here:
@dcavanagh and @remojansen, Do you have some guess about what is happening here?
As far as I know, it’s caused by
@babel/plugin-proposal-class-properties
.The code above was compiled to something like: