The issue is quite vague.
I am creating the project (code). It is a back-end, so I have an entry point to my server and a cli script that populates the database.
The problem is that my UserModel, that has a single dependency (a connection), can be container.get() from the CLI database script and fails when I try to start the server within the same project.
All annotations are set, 'reflect-metadata' is imported (even tried doing it several times :) ) and I see no differences between server and CLI scripts (regarding Inversify).
The UserModel instance can be acquired under any circumstances (see code).
When I try to import from server scripts, I get Cannot read 'name' of undefined error:
TypeError: Cannot read property 'name' of undefined
at Object.getFunctionName (/home/bogdan/nure/courseProject/DrOwn-server/node_modules/inversify/lib/utils/serialization.js:94:11)
at Object.getDependencies (/home/bogdan/nure/courseProject/DrOwn-server/node_modules/inversify/lib/planning/reflection_utils.js:11:43)
at /home/bogdan/nure/courseProject/DrOwn-server/node_modules/inversify/lib/planning/planner.js:106:51
at Array.forEach (<anonymous>)
at _createSubRequests (/home/bogdan/nure/courseProject/DrOwn-server/node_modules/inversify/lib/planning/planner.js:94:20)
at Object.plan (/home/bogdan/nure/courseProject/DrOwn-server/node_modules/inversify/lib/planning/planner.js:136:9)
at /home/bogdan/nure/courseProject/DrOwn-server/node_modules/inversify/lib/container/container.js:317:37
at Container._get (/home/bogdan/nure/courseProject/DrOwn-server/node_modules/inversify/lib/container/container.js:310:44)
at Container.get (/home/bogdan/nure/courseProject/DrOwn-server/node_modules/inversify/lib/container/container.js:230:21)
at Object.<anonymous> (/home/bogdan/nure/courseProject/DrOwn-server/dist/services/authentication.service.js:21:41)
at Module._compile (internal/modules/cjs/loader.js:688:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:699:10)
at Module.load (internal/modules/cjs/loader.js:598:32)
at tryModuleLoad (internal/modules/cjs/loader.js:537:12)
at Function.Module._load (internal/modules/cjs/loader.js:529:3)
at Module.require (internal/modules/cjs/loader.js:636:17)
None. I have tried all the pieces of advice from #584, #488 and #961 (the closest one, I think it is similar to mine).
The problem is I have tried to create minimalistic example that shows this error, but every time I tried to do this (outside and inside) the project I failed. In fact, it works even within current project (from the CLI database script). So my example is this project (sorry to bother you with >3000 dependencies :) ).
Steps to start the project:
git clone https://github.com/shevchenkobn/DrOwn-server.gitgit checkout f676ae87b13a8372e00401e2cd1e5bc04810032bnpm inpm start (the JS code is built and up-to-date; if you want to rebuild it run npm run build. In this case you would probably install devDependencies by npm i -D and npm run npm:g:dev or npm run npm:g:dev:win - global packages for development)
Possibly, the issue is connected with sideeffects of either Inversify with reflect-metadata or some other packages and may be relevant to other developers. Again, the issue is similar to #961
I really liked your package but, unfortunately, I have to use some alternative DI library. Hope the issues is resolved and I will get back to Inversify.
TypeError: Cannot read property 'name' of undefined
at Object.getFunctionName (/home/bogdan/nure/courseProject/DrOwn-server/node_modules/inversify/lib/utils/serialization.js:94:11)
at Object.getDependencies (/home/bogdan/nure/courseProject/DrOwn-server/node_modules/inversify/lib/planning/reflection_utils.js:11:43)
at /home/bogdan/nure/courseProject/DrOwn-server/node_modules/inversify/lib/planning/planner.js:106:51
at Array.forEach (<anonymous>)
at _createSubRequests (/home/bogdan/nure/courseProject/DrOwn-server/node_modules/inversify/lib/planning/planner.js:94:20)
at Object.plan (/home/bogdan/nure/courseProject/DrOwn-server/node_modules/inversify/lib/planning/planner.js:136:9)
at /home/bogdan/nure/courseProject/DrOwn-server/node_modules/inversify/lib/container/container.js:317:37
at Container._get (/home/bogdan/nure/courseProject/DrOwn-server/node_modules/inversify/lib/container/container.js:310:44)
at Container.get (/home/bogdan/nure/courseProject/DrOwn-server/node_modules/inversify/lib/container/container.js:230:21)
at Object.<anonymous> (/home/bogdan/nure/courseProject/DrOwn-server/dist/services/authentication.service.js:21:41)
at Module._compile (internal/modules/cjs/loader.js:688:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:699:10)
at Module.load (internal/modules/cjs/loader.js:598:32)
at tryModuleLoad (internal/modules/cjs/loader.js:537:12)
at Function.Module._load (internal/modules/cjs/loader.js:529:3)
at Module.require (internal/modules/cjs/loader.js:636:17)
I have fixed this issue.
If you have a complex project with lots of dependencies and you don't have to worry about the way they are resolved just add import './pass/to/your/di.container'; at the beginning of the file. di.container in this context is file where you create container and add all dependencies there. Example: https://github.com/shevchenkobn/NewCMMS-server/blob/master/src/di/container.ts
_Explanation:_
tl;dr: check your import tree manually. Consider moving objects managed by your DI into separate files in a type-per-file manner. It may be issue with circular imports or similar.
Node modules that have your @injectables probably import their @inject types directly (not for instantiation). Imports are done at the beginning of the file when @injectable type is not even declared. So if your module with @injectable is imported in DI container module, it _may_ get an undefined instead of your @injectable. That is what I had. Inversify tries to report the problem and fails.
Maybe a safeguard should be added to the library? It would be better to check if the type is undefined and report it before trying to read its name.
Something like Error: The dependency Symbol.for(type) is not defined. Consider reordering imports or import your container in the entry-point file.
@shevchenkobn I've run into this issue recently. Could you elaborate on what you mean by:
"If you have a complex project with lots of dependencies and you don't have to worry about the way they are resolved just add import './pass/to/your/di.container'; at the beginning of the file."?
@shevchenkobn I've run into this issue recently. Could you elaborate on what you mean by:
"If you have a complex project with lots of dependencies and you don't have to worry about the way they are resolved just add import './pass/to/your/di.container'; at the beginning of the file."?
I have updated the previous post. Please, reread the passage you quoted and tl;dr section.
Most helpful comment
I have fixed this issue.
If you have a complex project with lots of dependencies and you don't have to worry about the way they are resolved just add
import './pass/to/your/di.container';at the beginning of the file.di.containerin this context is file where you create container and add all dependencies there. Example: https://github.com/shevchenkobn/NewCMMS-server/blob/master/src/di/container.ts_Explanation:_
tl;dr: check your import tree manually. Consider moving objects managed by your DI into separate files in a type-per-file manner. It may be issue with circular imports or similar.
Node modules that have your
@injectables probably import their@injecttypes directly (not for instantiation). Imports are done at the beginning of the file when@injectabletype is not even declared. So if your module with@injectableis imported in DI container module, it _may_ get anundefinedinstead of your@injectable. That is what I had.Inversifytries to report the problem and fails.Maybe a safeguard should be added to the library? It would be better to check if the type is
undefinedand report it before trying to read its name.Something like
Error: The dependency Symbol.for(type) is not defined. Consider reordering imports or import your container in the entry-point file.