0

Making an app with a variety of schemas, many having other objects (Schema.Types.ObjectIds) as their properties.

When doing this, I can access the sub-object's property, as long as that sub-object's property is a string. But I'm having issues with it if that sub-object's property is yet another object (and then I need to query properties from that, string or not). For example, the first works fine:

user schema-> friends property of user (which is a list of user objects) -> username property of friend (which is a string)

But this I'm having issues with, I'm getting a string id and not the actual object**:

user schema-> profilePosts property of user (which is a list of profilePost objects) -> author property of profilePost (which is a user object)** -> author username property of profilePost (which is a string)

var mongoose = require("mongoose");
var Schema = mongoose.Schema;

var UserSchema = new Schema({
    username: {type: String, required: true},
    password: {type: String, required: true},
    friends: [{type: Schema.Types.ObjectId, ref: "User"}],
    profilePosts: [{type: Schema.Types.ObjectId, ref: "ProfilePost"}],
    friendRequests: [{type: Schema.Types.ObjectId, ref: "User"}], 

})

module.exports = mongoose.model('User', UserSchema);

var mongoose = require("mongoose");
var Schema = mongoose.Schema;

var ProfilePostSchema = new Schema({
    date: {type: Date, required: true},
    author: {type: Schema.Types.ObjectId, ref: "User"},
    content: {type: String, required: true},
    comments: [{type: Schema.Types.ObjectId, ref: "ProfilePostComment"}],
    likes: [{type: Schema.Types.ObjectId, ref: "User"}],
    hostProfile: {type: Schema.Types.ObjectId, required: true,ref: "User"},
})

module.exports = mongoose.model('ProfilePost', ProfilePostSchema);

exports.user_friends_render = async (req,res) => {
    try {
        const ViewedProfile = await User.find({}, 'username friends profilePosts friendRequests').populate('friends').populate('profilePosts').populate('friendRequests');
        res.status(200).json(ViewedProfile);
    } catch(error) {
        res.status(200).json({message: error.message});
    }
}

objects are string ids instead of objects

roberts4
  • 1
  • 3

1 Answers1

0

Mongoonse populate root object but not implicit deep populate

You can replace string by object as argument at populate method, for provide full path to populate

const ViewedProfile = await User
  .find({}, 'username friends profilePosts friendRequests')
  .populate('friends')
  .populate({
    path: "profilePosts",
    populate: [
      {
        path: "author",
        // model: UserModel
      },
      {
        path: "comments",
        // model: ProfilePostCommentModel
      },
      {
        path: "likes",
        // model: UserModel
      },
      {
        path: "hostProfile",
        // model: UserModel 
      }
    ]
  })
  .populate('friendRequests');

You can see fully post at this problem.

GABORIEAU
  • 61
  • 3
  • Ok thanks, that might work soon but right now when I add the populate you wrote above I'm getting an error and the app crashes {message: 'Cast to ObjectId failed for value "eden1" (type string) at path "_id" for model "User"'} – roberts4 Feb 28 '22 at 17:32
  • any idea why this is? – roberts4 Feb 28 '22 at 17:47
  • either that, or the array im looking for just ends up being empty – roberts4 Feb 28 '22 at 20:24
  • I think, that **mongoose** find value `"eden1"` instead of `ObjectId`. If you has add test data into collections you will should remove (or replace with valid data format) this before use method `populate`. Can see other topic with [same problem at stackoverflow](https://stackoverflow.com/questions/14940660/whats-mongoose-error-cast-to-objectid-failed-for-value-xxx-at-path-id) – GABORIEAU Mar 01 '22 at 09:30