SoftwareBrothers / adminjs-mongoose

Mongoose adapter for AdminJS

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Mongoose Virtuals do not work

EricHier opened this issue · comments

As shown in this example, mongoose supports virtual (computed) properties on objects. I've implemented an example resource (just like the first one in the mongoose docs) and I am not able to show the property in the frontend.

What do I miss? Are virtuals supported in admin-bro-mongoose?

I struggled to get them working too for quite some time now and I found a way to do it (or at least display them in adminbro). You have to add a mongoose middleware for it to automatically populate your virtual field before they get to adminbro. I think simplest answer would be to do this:

Mongoose schema definition:

const schema = new mongoose.Schema({
    name: {
        type: String,
        required: false
    },
}, {
    timestamps: true,
    toJSON: { virtuals: true },
    toObject: { virtuals: true }
});

schema.virtual('VIRTUAL_FIELD', {
    ref: "...",
    localField: "...",
    foreignField: '...',
});

// here you populate your virtual field before it gets returned to adminbro (find query)
schema.pre('find', function () {
    this.populate('VIRTUAL_FIELD');
});

module.exports = mongoose.model('schema', schema);

Thank you for your solution! :) Don't you think that adminbro-mongoose should populate the fields automatically? This would be expected behaviour from my view. This would also allow you to only populate the field when using adminbro and not on every query on the schema.

It didn't work for me. I'm a little confused now.
Actually I'm beginner with MongoDB so my question is: Does virtual really need to set foreignField and localFields ? As I know, virtuals are defined as:

const virtual = AffiliateSchema.virtual('fullname');
virtual.get(function(value, virtual, doc) {
  return "Test"
});

Just for viewing purposes, of couse.

I can confirm they are not working. Also what I see is that if the _id field is not of type ObjectId the adminjs do not properly builds the link in the relation.
Like this:

// On one side
champion: { type: String, required: true, ref: 'Champions' },

// On the other side
_id: {
  type: String,
  required: true,
  unique: true,
}