Overview
FYI : I uploaded a complete project to GitHub. Feel free to download and see for yourself.
I created this project to identify a problem with NestJS, Mongoose and MongoDB. At a high level, the problem is targeting multiple databases from within the project. It seems like NestJS wants to add the suffix 'Model'
somewhere in the process.
In my actual application, I am trying to ensure a document is uploaded to MongoDB (…which is easy enough). I have to do some transformation work on the documents later, like on a scheduled job. Once the job is complete, I want to store the transformed document in a separate container.
I use the term "container" generically, here — I don’t care if it’s a database or a collection in the same database.
I would prefer to not modify my data such that I am sticking with the easy route (which means everything goes in the generic fs.files
and fs.documents
collections in the same database). I mean, the mechanisms are there and pretty well documented, so not sure why this vanilla example isn’t working. Also, yes, I assumed that I would have to use two, separate databases since I don’t imagine MongoDB (let alone Mongoose) provides the mechanisms for renaming those two collections. I am identifying the two, separate connections in the root AppModule
as firstCxn
and secondCxn
so they can be referred to in their respective Module definitions.
A Few Things I’ve Tried
- I thought there might be some kind of undocumented, explicit naming convention I was missing out on, so I went back and renamed the entities. I added
'Model'
to the ends of their names. That’s when I started seeing this whole'...ModelModel'
issue. - When referencing the models in decorators, I used explicit string values where strings are allowed. For example, in the
first.server.ts
, I added@InjectModel('First')
instead of@InjectModel(FirstModel.name)
. - Added a reference to the
FirstModel
class in theFirstModule
definition, right before theMongooseModule.forFeature(...)
.- This seemed to provide some forward progress. Well…at least, when I changed it in the
FirstModule
, I started getting the same error for theSecondModule
.
- This seemed to provide some forward progress. Well…at least, when I changed it in the
Error Output
This is what I get as the output in my debug console…
Debugger attached.
(node:27751) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
[Nest] 27751 - 12/11/2023, 2:57:23 PM LOG [NestFactory] Starting Nest application...
[Nest] 27751 - 12/11/2023, 2:57:23 PM LOG [InstanceLoader] SecondModel dependencies initialized +41ms
[Nest] 27751 - 12/11/2023, 2:57:23 PM LOG [InstanceLoader] MongooseModule dependencies initialized +0ms
[Nest] 27751 - 12/11/2023, 2:57:23 PM LOG [InstanceLoader] MongooseModule dependencies initialized +0ms
[Nest] 27751 - 12/11/2023, 2:57:23 PM ERROR [ExceptionHandler] Nest can't resolve dependencies of the FirstsService (?). Please make sure that the argument "FirstModelModel" at index [0] is available in the FirstModule context.
It seems that NestJS is looking for something with an additional
'Model'
at the end of the name.
Questions
- Has anyone seen this before?
- …anything obvious jumping out?
- Are there any good examples of using NestJS, Mongo and Mongoose with multiple databases/collections out there?
Bonus Questions
- If teflon is so awesome, why does it stick to the pan?
- Will the Sonny ever get some Trix? …is Sonny still even alive?
- If a duck eats lunch and then goes swimming right away, does it get a cramp?
2
Answers
[Insert
:facepalm:
HERE]Looks like what I was glossing over as a kind of "belt and suspenders" approach is actually just "the approach".
When injecting the model name in
@InjectModel
, it is absolutely required to specify the connection name there as well. So, my code looks like this: