Search code examples
node.jsmongoosemongoose-populate

Calculate custom property based on populate element


I have two Schemas : recipe and product

var recipeSchema = new mongoose.Schema({
    name: {
        type: String,
        required: true
    },
    products: [{
        product: { type: mongoose.Schema.Types.ObjectId, ref: 'Product' },
        productWeight: Number,
        productPrice: Number
    }]
})

var productSchema = new mongoose.Schema({
    name: {
        type: String,
        required: true
    },
    weight: {
        type: Number,
        required: true
    },
    price: {
        type: Number,
        required: true
    }
})

And I have addRecipe function

module.exports.addRecipe = function(req, res){
    Recipe
        .create({
            name: req.body.name,
            products: req.body.products
        }, function(err, recipe){
            if(err){
                console.log("Error creating recipe");
                res
                    .status(400)
                    .json(err);
            } else {
                console.log("Recipe created", recipe);
                res
                    .status(201)
                    .json(recipe);
            }
        })
}

I'd like to calculate productPrice for every object in array (productPrice = product.price * productWeight / product.Weight).

My posted JSON.

{
    "name": "Cake",
    "products": [
        {
            "product": "59728a3f7765441b503e31bc",
            "productWeight": 100
        },
        {
            "product": "59728a3f7765441b503e31bd",
            "productWeight": 200
        },
        {
            "product": "59728a3f7765441b503e31be",
            "productWeight": 50
        },
        {
            "product": "59728a3f7765441b503e31bf",
            "productWeight": 500
        }
    ]
}

I'd like also update productPrice on product or reicpe edit. Is it possible to do this?

Thanks!


Solution

  • I would use a virtual for this, but I don't think it is possible to use it without introducing another schema.

    var RecipeProductSchema = new mongoose.Schema({
        product: { type: mongoose.Schema.Types.ObjectId, ref: 'Product' },
        productWeight: Number
    });
    
    // note: product must be populated before calling this property
    RecipeProductSchema.virtual('productPrice').get(function() {
        return this.product.price * this.productWeight / this.product.weight;
    });
    
    var RecipeSchema = new mongoose.Schema({
        name: {
            type: String,
            required: true
        },
        products: [RecipeProductSchema]
    })