Search code examples
node.jsmongodbexpressmongoosemongoose-schema

MongoDB - Mongoose: How to query this? "populate()" dosen't work. it's show "null"


I have a page schema, the page schema has two object properties createdBy and approvedBy.

when I used .populate("approvedBy").populate("createdBy"); then show "approvedBy": null , "createdBy": null,

When I don't use populate() just use find() and then show the ObjectId. But I need all the nested objects like using populate().

Page Schema:

const mongoose = require("mongoose");

const PageSchema = new mongoose.Schema({
  title: {
    type: String,
    require: true,
  },
  description: {
    type: String,
    require: true,
  },
  url: {
    type: String,
  },
  logoURL: {
    type: String,
  },
  backgroundImageURL: {
    type: String,
  },
  button: {
    title: {
      type: String,
      require: true,
    },
    url: {
      type: String,
    },
    color: {
      type: String,
    },
  },
  createdBy: {
    type: mongoose.Types.ObjectId,
    ref: "User",
    require: true,
  },
  approvedBy: {
    type: mongoose.Types.ObjectId,
    ref: "User",
    require: true,
  },
  approve: {
    type: Boolean,
    default: false,
  },
  approveDate: {
    type: Date,
  },
  archive: {
    type: Boolean,
    default: false,
  },
  archiveDate: {
    type: Date,
  },
  createdAt: {
    type: Date,
    default: Date.now,
  },
  updatedAt: {
    type: Date,
  },
});

module.exports = mongoose.model("Page", PageSchema);

by using find()code:

const pages = async (req, res, next) => {
  try {
    const pages = await Page.find({})
      .populate("approvedBy")
      .populate("createdBy");
    if (pages === null || pages.length == 0) {
      throw createError(404, "NO DATA FOUND");
    }
    return res.status(200).json({ success: 1, pages });
  } catch (error) {
    return next(createError(error));
  }
};

by using find() output:

{
    "success": 1,
    "pages": [
        {
            "button": {
                "title": "Play Now",
                "url": "btnURL",
                "color": "#ff6767"
            },
            "_id": "6425a0d069c436a4f056ba26",
            "title": "Dengen NFT 2",
            "description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
            "url": "imgURL",
            "logoURL": "logoURL",
            "backgroundImageURL": "bgURL",
            "createdBy": "64231bf9f21deb779a148c64",
            "approve": false,
            "archive": false,
            "createdAt": "2023-03-30T14:46:40.312Z",
            "__v": 0,
            "approvedBy": "64231b8a6c0398e50a8472d1"
        }
    ]
}

by using .populate("approvedBy").populate("createdBy") code:

const pages = async (req, res, next) => {
  try {
    const pages = await Page.find({}).populate("approvedBy", "createdBy");
    if (pages === null || pages.length == 0) {
      throw createError(404, "NO DATA FOUND");
    }
    return res.status(200).json({ success: 1, pages });
  } catch (error) {
    return next(createError(error));
  }
};

by using .populate("approvedBy").populate("createdBy") output:

"approvedBy": null , "createdBy": null,

{
    "success": 1,
    "pages": [
        {
            "button": {
                "title": "Play Now",
                "url": "btnURL",
                "color": "#ff6767"
            },
            "_id": "6425a0d069c436a4f056ba26",
            "title": "Dengen NFT 2",
            "description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
            "url": "imgURL",
            "logoURL": "logoURL",
            "backgroundImageURL": "bgURL",
            "createdBy": null,
            "approve": false,
            "archive": false,
            "createdAt": "2023-03-30T14:46:40.312Z",
            "__v": 0,
            "approvedBy": null
        }
    ]
}

Solution

  • You say that you're using:
    .populate("approvedBy").populate("createdBy")
    But you have posted this:
    .populate("approvedBy", "createdBy"), I'm not sure it works.

    This code works, perhaps you can take something away from it:

    import mongoose from "mongoose"
    
    const UserSchema = new mongoose.Schema({
        name: String
    })
    
    const PageSchema = new mongoose.Schema({
        createdBy: {
            type: mongoose.Types.ObjectId,
            ref: "User",
            require: true,
        },
        approvedBy: {
            type: mongoose.Types.ObjectId,
            ref: "User",
            require: true,
        },
    });
    
    const Page = mongoose.model("Page", PageSchema);
    const User = mongoose.model("User", UserSchema);
    
    const run = async () => {
        await mongoose.connect('mongodb://127.0.0.1:27017/75890536');
        const { _id } = await User.create({ name: "username" })
    
        await Page.create(
            {
                createdBy: _id,
                approvedBy: _id
            })
    
        const page = await Page.find().populate("createdBy").populate("approvedBy")
        console.log(page)
    
        await mongoose.disconnect()
    }
    run()
    

    Output:

    [
      {
        _id: new ObjectId("6425c5a767056db481c1f77f"),
        createdBy: {
          _id: new ObjectId("6425c5a767056db481c1f77d"),
          name: 'username',
          __v: 0
        },
        approvedBy: {
          _id: new ObjectId("6425c5a767056db481c1f77d"),
          name: 'username',
          __v: 0
        },
        __v: 0
      }
    ]
    

    node: v18.12.1 mongo v6.0.1