I've been looking at nestjs as a framework to use and started running through their documentation. One of the things that I was a bit confused by was the database documentation. I ran into an issue that I couldn't figure out until now and I'm going to run through how it was fixed.
Let's start with some context on what I was trying to do. I wanted to create a
DatabaseModule that would hold the connections to all of my databases and would search through specific paths for entities. I then wanted to use that module where necessary to connect to the database. My first test was with the
UserService. So I had created a
database-connections.ts file which had the connection to the main database set up,
At the moment it's just one entry but this could be as many entries as you want. In the
entites array, I specify the path to the entities that would be applicable to the database.
Cool so the connection is set up! The next step is to create the
DatabaseModule that I can use in other places,
Basically, all I'm doing here is importing the database connections and exporting them. THIS IS WRONG!! You need to keep reading on if you did the same because it's what caused the error that I couldn't explain. We're not looking to export each
TypeOrmModule like I've done above. I'm going to keep going to show what happens if you do this.
Okay sweet so we have the database module (it doesn't work but we don't know that yet). The next step is to create a
SharedModule that has a couple of services and other things that we want all modules to use. In this case, the
UserService is what I'd like to create and share with all of my modules. So let's first make the
user.entity.ts file looks like this,
Okay great, we've set up the entity and service, let's create the
So you can see here that I'm sharing the
DatabaseModule and I'm also providing the
UserService here. This is where it gets interesting. If you build and run this you'll get the following error,
[Nest] 647 - 2018-8-18 17:21:48 [ExceptionHandler] Nest can't resolve dependencies of the UserService (?). Please make sure that the argument at index  is available in the current context. Error: Nest can't resolve dependencies of the UserService (?). Please make sure that the argument at index  is available in the current context. at Injector.lookupComponentInExports (/app/node_modules/@nestjs/core/injector/injector.js:129:19) at <anonymous> at process._tickCallback (internal/process/next_tick.js:118:7) at Function.Module.runMain (module.js:692:11) at Object.<anonymous> (/app/node_modules/ts-node/src/_bin.ts:177:12) at Module._compile (module.js:649:30) at Object.Module._extensions..js (module.js:660:10) at Module.load (module.js:561:32) at tryModuleLoad (module.js:501:12) at Function.Module._load (module.js:493:3) 1: node::Abort() [/usr/local/bin/node] 2: 0x8cea99 [/usr/local/bin/node] 3: v8::internal::FunctionCallbackArguments::Call(void (*)(v8::FunctionCallbackInfo<v8::Value> const&)) [/usr/local/bin/node] 4: 0xb1444c [/usr/local/bin/node] 5: v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**, v8::internal::Isolate*) [/usr/local/bin/node] 6: 0x165e75e042fd Aborted (core dumped)
Flip... I can see that the issue is with the first entry in the constructor of the
UserService but apart from that, it's pretty hard to see whats wrong. One great clue is that if you remove all of your database imports and run the code, you get the same error. This implies that those database imports and exports aren't working as expected. So what did I do wrong? I exported the
TypeOrmModule.forRoot calls from the
DatabaseModule when I should have just exported
TypeOrmModule. I also didn't import the
TypeOrmModule.forFeature in the
SharedModule. So to fix this issue, we need to do two things, first we need to change the
The second thing we need to do is import the
TypeOrmModule using the
forFeature call in the
And that's it, everything runs smoothly and we're able to run our nestjs application :) In any modules, make sure to call
TypeOrmModule.forFeature([... the applicable entities go here]) and you should be good to go!
If you're looking to extend your entities with
BaseEntity so that you don't need to inject a repository, then you'll need to name your database
default in the
database-connections.ts file. So in my case
Config.get.databases.main.name would return the string
default and, because of that, I can use the Active Record pattern.