Mrugesh
Mrugesh

Reputation: 4517

mongoose is not able to populate ref id with default value empty object

My schema is as shown below:

const order = new Schema({
    order_status: Number, 
    foodtruck_id: { type: Schema.Types.ObjectId, ref: 'foodtruck' },
    customer_id: { type: Schema.Types.ObjectId, ref: 'user' },
    items: [{ type: Schema.Types.ObjectId, ref: 'items' }],
    user_type: Boolean,
    order_time: Date,
    order_rating: { type: Number, default: 5.0 },
    order_issue_comments: String,
    order_special_instruction: String,
    order_total: Number,
    order_location: String,
    order_coupon_code: String,
    payment_id: { type: Schema.Types.ObjectId, ref: 'payment' },
    order_meta: { type: Schema.Types.Mixed, ref: 'order_sub_info', default: {} }
}, { versionKey: false }, { minimize: false });

my query is as shown below:

order.find({
        'foodtruck_id': foodtruck_id.trim()
    }).populate('customer_id', {
        '_id': 1,
        'user_name': 1,
        'email_id': 1,
        'ph_no': 1,
        'login_type': 1
    }).populate('items').
    populate('order_meta', 'order_otp').exec((err, orderList) => {
        if (err) res.json({
            status: '500',
            message: err
        });
        else {
            console.log("called");
            res.json({
                status: '200',
                message: 'Order list',
                data: orderList
            });
        }
    });

For this query,it is giving me Cast to ObjectId failed for value at path _id as order_meta has default value {}. How to have effective populate query so that It can take care of this testcase?

Upvotes: 2

Views: 1608

Answers (1)

libik
libik

Reputation: 23029

It is not good idea to put empty object in a place, where reference id is expected. Both - for having problem with populate and for common sense too (if it is field which has reference, it should be null/undefined or reference itself).

It is common that you want to transform your data at some endpoint, but it should not interfere with database or business logic of application.

You can defined toJSON method that should be used for your model. In your case

const order = new Schema({
    order_status: Number, 
    foodtruck_id: { type: Schema.Types.ObjectId, ref: 'foodtruck' },
    customer_id: { type: Schema.Types.ObjectId, ref: 'user' },
    items: [{ type: Schema.Types.ObjectId, ref: 'items' }],
    user_type: Boolean,
    order_time: Date,
    order_rating: { type: Number, default: 5.0 },
    order_issue_comments: String,
    order_special_instruction: String,
    order_total: Number,
    order_location: String,
    order_coupon_code: String,
    payment_id: { type: Schema.Types.ObjectId, ref: 'payment' },
    order_meta: { type: Schema.Types.ObjectId, ref: 'order_sub_info'}
}, { versionKey: false }, { minimize: false });

order.options.toJSON = {
        transform(zipRequestDocument, ret, options) { // eslint-disable-line no-unused-vars
            if (!ret.order_meta){
                 ret.order_meta = {};
            }
        },
    };

Upvotes: 1

Related Questions