Angelo Pettinelli
Angelo Pettinelli

Reputation: 53

Mongoose populate does not populate

I have two collections into my MongoDB database: users and components.

The users' primary key is _id which is Number. It is referenced by the created_by and updated_by fields of a component document.

Everything works well except for the populate and I can't figure it out why. It leaves the value instead of the corresponding user document. I also tried to use ObjectIds instead of Numbers but nothing changed.

Any help will be appreciated.

I listed above the models and routing sources.

Component and User models

models/user.js

import mongoose from 'mongoose';

const userSchema = new mongoose.Schema({
    _id: Number,
    firstName: String,
    lastName: String,
    email: String,
    password: String,
});

const User = mongoose.model('User', userSchema);

export default User;

models/component.js

import mongoose from 'mongoose';

const componentSchema = new mongoose.Schema({
    name: String,
    category: String,
    package: String,
    box: Number,
    cell: Number,
    quantity: Number,
    note: String,
    link: String,
    created_by: {
        type: Number,
        ref: 'User'
    },
    created_on: Date,
    updated_by: {
        type: Number,
        ref: 'User'
    },
    updated_on: Date
});

const Component = mongoose.model('Component', componentSchema);

export default Component;

models/index.js

import Component from './component';
import User from './user';

const models = { Component, User };

export default models;

Middleware

import models from './models';

app.use((req, res, next) => {
    req.context = { models };
    next();
});

Components routing

import { Router } from "express";
const router = Router();
...
var getComponents = async (req, res) => {
    const query = req.context.models.Component.find().populate('users');

    try {
        const results = await query;
        return res.status(200).send({ results: results });
    } catch (err) {
        return res.status(400).send({ error: err });
    }
}
...
router.get('/', getComponents)

export default router;

I also tried to use the exec

var getComponents = (req, res) =>
    req.context.models.Component.find().populate('users').exec().then(components => res.status(200).send({ results: components })).catch(err => res.status(400).send({ error: err }));

but I got the same result.

Upvotes: 0

Views: 181

Answers (3)

SuleymanSah
SuleymanSah

Reputation: 17888

You just need to use an existing field name in populate path like .populate('created_by')

Here is the test:

I first created a user with this request body:

{
    "_id": 111,
    "firstName": "John",
    "lastname": "River",
    "email": "abc@def.net",
    "password": "123123"
}

Then I created two components:

{
    "name": "component 1",
    "quantity": 1,
    "created_by": 111
}

And

{
    "name": "component 2",
    "quantity": 2,
    "created_by": 111
}

And using this code:

const result = await Component.find().populate("created_by");

The result is:

[
    {
        "_id": "5de7a89e9039c738b4008d41",
        "name": "component 1",
        "quantity": 1,
        //other fields
        "created_by": {
            "_id": 111,
            "firstName": "John",
            "email": "abc@def.net",
            "password": "123123",
            "__v": 0
        },
        "__v": 0
    },
    {
        "_id": "5de7a8aa9039c738b4008d42",
        "name": "component 2",
        "quantity": 2,
        //other fields
        "created_by": {
            "_id": 111,
            "firstName": "John",
            "email": "abc@def.net",
            "password": "123123",
            "__v": 0
        },
        "__v": 0
    }
]

Upvotes: 1

Pushprajsinh Chudasama
Pushprajsinh Chudasama

Reputation: 7969

you can do somthing like this.

created_by: { type:Schema.Types.ObjectId, ref: 'User' }

And query

Component.find().populate('created_by');

Upvotes: 1

Shihab
Shihab

Reputation: 2679

I believe it would be:

created_by: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }

Then, query like this,

Component.find().populate('created_by');

Upvotes: 1

Related Questions