'How to call a mongoose schema method inside a controller?

This is my MongooseModel

const mongoose = require('mongoose');
const { boolean } = require('webidl-conversions');

const memberSchema = mongoose.Schema({
    name:{
        type:String,
        required:[true,"Please enter Customer Name"]
    },
    age:{
        type:Number,
        required:[true,"Please enter your age"]
    },
    address:{
        type:String,
        required:[true,"Please enter your Address"]
    },
    phone:{
        type:String,
        required:[true,"Please enter your phone number"],
        minLength:[10,"Phone number must be 10 digits"],
        maxLength:[10,"Phone number must be 10 digits"],

    },
    avatar:{
        public_id:String,
        url:String

    },
    joining:{
        type:Date,
        default:Date.now
    },
    status:{
        type:Boolean,
        default:true,
    },
    membership:{
        user:{
            type:mongoose.Schema.ObjectId,
            ref:"Member",
        },
        membershipAmount:{
            type:Number,
          
        },
        membershipStart:{
            type:Date,
           
        },
        membershipPeriod:{
            type:Number,
        },
        membershipEnd:{
            type:Date,
           
        },
        signUpFee:{
            type:Number,
            default:500
        }


    },
    
});

module.exports=mongoose.model("Member",memberSchema);

memberSchema.methods.planValidity=function(){
    this.membershipEnd=new Date(this.membershipStart+(this.membershipPeriod*24*60*60*1000));
    
}

Now I want to use this method planValidity inside a controller while creating a new user.

exports.addMember = catchAsyncErrors(async(req,res,next)=>{

    const member = await Member.create(req.body);
       

    res.status(201).json({
        success:true,
        member
    });


});

How do I call the method so that my MembershipStart and membershipEnd gets updated.



Solution 1:[1]

Something like this might work.

const memberLookup = await Member.findOne({"name":req.body.name});
if (memberLookup != null) {

    memberLookup.member.membershipEnd = new Date(memberLookup.member.membershipStart+(memberLookup.member.membershipPeriod*24*60*60*1000));

    const member = await Member.findOneAndUpdate({"name":req.body.name}, {$set:{"membership.membershipEnd":memberLookup.member.membershipEnd}},{'upsert':true});

    }
});

Solution 2:[2]

I don't really understand what's the problem you're having.

  1. You need to fix your planValidity method. Both membershipEnd and membershipPeriod are under membership property.
    memberSchema.methods.planValidity=function(){ this.membershipEnd=new Date(this.membershipStart+(this.membershipPeriod2460601000)); }

  2. After fixing the method, you can just call it as a normal function:

const mem = new Member({  
      ...  
      membership: {  
        membershipStart: new Date(),  
        membershipPeriod: 1,  
      },
    });
mem.planValidity();
mem.save();

Solution 3:[3]

If membershipStart and membershipPeriod properties are initialized while creating Member then, mongoose prehook(save) can be used to update the membershipEnd property.

mongoose middleware documentation link: https://mongoosejs.com/docs/middleware.html#pre

memberSchema.pre('save', function() {
    this.membership.membershipEnd = new Date(this.membership.membershipStart + (this.membership.membershipPeriod * 24 * 60 * 60 * 1000));
});

Note: All mongoose document instance methods must define before the model created.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Stephen Taylor
Solution 2 Jimmy
Solution 3 Tyler2P