Using Mongoose's Populate in Next.Js
JanetTheDev
Posted on February 17, 2023
Overview of What We're Doing
In the namecategories collection in MongoDB, we want to replace the object ids in tags, with the matching objects in the name tags Collection
So the end result will be:
name: "games"
tags: [
0: {_id: ...., nameTag: "I love you colonel Sanders", __v:0}
1: {_id: ...., nameTag: "Hatoful Boyfriend", __v:0}
2: {_id: ...., nameTag: "Dream Daddy", __v:0}
3: {_id: ...., nameTag: "Sephiroth", __v:0}
]
The Setup
The Page Calling the API
The models:
The API:
The Problem
Every time I tried to populate with my "NameTag" collection {} was returned.
However when I populated with my "User" collection it worked??๐คจ
TLDR answer if you're having the same problem:
Import the model you're populating with. Even though it will be greyed out, the import is needed for the populate to work
The Debugging Process
Testing to see if we can grab data from the "NameTags" database
I kept thinking "huh it seems like mongoose isn't able to communicate with the collection for some reason". And turns out this hunch was key to solving the problem!
So I tried to do NameTag.Find() to see if even that would work. And, wait for it...๐ฅ๐ฅ๐ฅ I originally got {} back.
Doh, of course it's {} since I didn't import the NameTag model on the top! ๐คฆ๐
After it was imported it worked! Ta-dah!
Then when I switched back to trying populate, it worked!
When I removed "import NameTag from '../../../models/NameTag'" from the top and saved it initially worked. But when I restarted the terminal it no longer worked.
When the import was re-added and the terminal restarted, it worked! So the import was key.
Why the User Model worked but NameTags didn't
The user model was imported in other app\pages
However the NameTag model wasn't! To test this theory I moved the import out of the app\pages\api\name-categories file and into the app\pages\api\auth file.
And what do you know the populate still works!
Working code
Basic Build Information:
"mongodb": "^4.13.0",
"mongoose": "^6.8.0",
"next": "12.3.1",
"node": "18.2.0"
Newest versions as of today:
"mongodb": "6.0.0"
"mongoose": "6.9.2"
"next" : "13.1.6"
"node" : "18.14.1 LTS/ 19.6.1 current"
My mongodb dependency is out of date, so that might be what's causing this bug and requiring the workaround.
Bonus! Ways to write out Populate
In the process of debugging I discovered there's many ways to write populate! So here's options for you to choose from:
- .populate( {path:"propertywithobjectids", model:"modelname"} ) + don't add ref to the model
2.populate(
{path:"propertywithobjectids"}
)
+
add ref inside the property which has the list of object ids to populate
Special note:
the [{ }] syntax must be used, since you're creating an array of objects
Import schema:
import {Schema} from "mongoose"then type:
type: Schema.Types.ObjectId,
3 populate(
"propertywithobjectids"
)
+
add ref inside the property which has the list of object ids to populate
If you don't want to import {Schema} from "mongoose" you can write
Type:mongoose.Schema.Types.ObjectId
Posted on February 17, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.