Using Mongoose's Populate in Next.Js
Tags: mongodb, nextjs, programming, database
Published: 2023-02-17 05:57:14

## Overview of What We're Doing

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/knk25b4ku6wuv1bdh1mx.png)

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

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m47kt6yu7togmmgc3vk7.png)


### The models:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zigqiyol44xw5d9xcsya.png)

### The API:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i2nkuj3tn3vy6utgzf5v.png)

## The Problem
Every time I tried to populate with my "NameTag" collection {} was returned. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rsjxg7fd187xskr3kzus.png)

However when I populated with my "User" collection it worked??🤨

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ls7hwi5c85a3apz7pnbc.png)

## 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

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wni6v82byg7w2ae7oqhe.png)

## 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!

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pvjo449poei9nrksi5fb.png)

Then when I switched back to trying populate, it worked!

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pu8sv6qjlu8923lr7zqc.png)

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. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v8xvwct3aol0lpkzagni.png)

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

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xulqwx5bcgnvg0o2csjz.png)

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. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/85bejh5o775qxl6kye61.png)

And what do you know the populate still works! 

## Working code

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4gvlg4msg7m1c8obi9h1.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j163d2kde7pim5gb1rt8.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8gctj2m7jzeekmrnccfc.png)

##  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:

1. .populate(
{path:"propertywithobjectids", model:"modelname"}
) 
+
don't add ref to the model
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y0lsq6erk6q0m3l87bn8.png)

2.populate(
{path:"propertywithobjectids"}
) 
+
add ref inside the property which has the list of object ids to populate

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/468u0iqkasrhnvudy1y3.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r9gzghy6wz5jz5m016vc.png)

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

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/10dkgzy3vvcdtfgecxgb.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y9ezlr9gqf2s90v1d2q6.png)

If you don't want to import {Schema} from "mongoose" you can write
Type:mongoose.Schema.Types.ObjectId