mongodb-js / mongoose-autopopulate

Always populate() certain fields in your mongoose schemas
Apache License 2.0
222 stars 36 forks source link

autopopulate results to null in depth level 2 #43

Closed ghost closed 6 years ago

ghost commented 6 years ago

I started using mongoose-autopopulate, as I've been annoyed of manually typing the populate paths. I developed a service which stores post in a mongodb database and links to an user id stored, used for authentication too. Everything works fine, but when I try to add a comment to a post linked to an user account, too, the user in the comment is not populated (I'll get null). I had a look in my database and everything works correctly, the database is storing the right links.

.get((req, res) => {
        PostModel.findById(req.params.id, (err, post) => {
            if (err){
                res.status(500).json({
                    success: false,
                    message: 'internal server error'
                });
            } else if (!post) {
                res.status(404).json({
                    success: false, 
                    message: 'post doesn\'t exist'
                });
            } else {
                res.status(200).json({
                    success: true,
                    message: 'post succesfully queried',
                    data: post
                });
            }
        });
    })

My query that returns the populated post

Database

{"_id":{"$oid":"5b455bb3124880076a145d45"},"published":true,"comments":[{"$oid":"5b455bd2124880076a145d46"}],"title":"e","content":"e","author":{"$oid":"5b442c426bdeb91233486f0b"},"createdAt":{"$date":{"$numberLong":"1531272115219"}},"updatedAt":{"$date":{"$numberLong":"1531272146141"}},"__v":{"$numberInt":"0"}}

My post

{"_id":{"$oid":"5b455bd2124880076a145d46"},"content":"test comment","author":{"$oid":"5b442c426bdeb91233486f0b"},"createdAt":{"$date":{"$numberLong":"1531272146098"}},"updatedAt":{"$date":{"$numberLong":"1531272146098"}},"__v":{"$numberInt":"0"}}

My comment

{"_id":{"$oid":"5b442c426bdeb91233486f0b"},"permissions":{"admin":false,"blog":true},"verfied":false,"disabled":false,"username":"s","email":"a.a@a.com","password":"$2b$10$M5a9eQz3fMVOc/VKBV8ndOX8kpG1e1nCf7RuQ2ABs4IU3MXKUW4Uy","createdAt":{"$date":{"$numberLong":"1531194434294"}},"updatedAt":{"$date":{"$numberLong":"1531194434294"}},"__v":{"$numberInt":"0"}}

And my user.

As you can see, everything is alright in the database itself, but when I use the query with mongoose using these schemas

Schemas

const PostSchema = new Schema({
    title: {
        type: String,
        unique: true,
        trim: true,
        maxlength: 256
    },
    content: {
        type: String,
        trim: true,
        maxlength: 100000
    },
    published: {
        type: Boolean,
        default: true
    },
    author: {
        type: Schema.Types.ObjectId,
        ref: 'User',
        required: true,
        autopopulate: {select: ['username', 'email']}
    },
    comments: [{
        type: Schema.Types.ObjectId,
        ref: 'Comment',
        autopopulate: true
    }]
}, {
    timestamps: true,
    strict: true
});

PostSchema.plugin(autopopulate);

const Post = mongoose.model('Post', PostSchema);
module.exports = Post;

Post.js

const UserSchema = new Schema({
    username: {
        type: String,
        unique: true,
        required: true,
        trim: true,
        maxlength: 256
    }, 
    password: {
        type: String,
        required: true,
        trim: true,
        maxlength: 256
    },
    email: {
        type: String,
        unique: true,
        required: true,
        trim: true,
        lowercase: true,
        match: /^[a-z0-9_\-.+"]+@([a-z0-9.-])+\.([a-z0-9]{2,})$/,
        maxlength: 256
    },
    permissions: {
        admin: {
            type: Boolean,
            default: false
        },
        blog: {
            type: Boolean,
            default: false
        }
    },
    verfied: {
        type: Boolean,
        default: false
    },
    disabled: {
        type: Boolean,
        default: false
    }
},{
    timestamps: true,
    strict: true
});

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

User.js

const CommentSchema = new Schema({
    content: {
        type: String,
        required: true,
        maxlength: 1000
    },
    author:  {
        type: Schema.Types.ObjectId,
        required: true,
        autopopulate: {select: ['username', 'email']}
    }
},{
    timestamps: true,
    strict: true
});

CommentSchema.plugin(autopopulate);

const Comment = mongoose.model('Comment', CommentSchema);
module.exports = Comment;

Comment.js

I'll get

{"success":true,"message":"post succesfully queried","data":{"published":true,"comments":[{"_id":"5b455bd2124880076a145d46","content":"test comment","author":null,"createdAt":"2018-07-11T01:22:26.098Z","updatedAt":"2018-07-11T01:22:26.098Z","__v":0}],"_id":"5b455bb3124880076a145d45","title":"e","content":"e","author":{"_id":"5b442c426bdeb91233486f0b","username":"s","email":"a.a@a.com"},"createdAt":"2018-07-11T01:21:55.219Z","updatedAt":"2018-07-11T01:22:26.141Z","__v":0}}

The reference to the user is null, I don't have any idea if I do something wrong or if this is a bug. Please tell me if I did something wrong. Kjell

vkarpov15 commented 6 years ago

It looks like your comment doesn't have an author property, that's why you get author = null in your comment doc.