I have MemberProfiles and MemberPayments collections.The MemberProfile has expiryDate field which is set to current date at insert.I need to extend expirDate of a unique MemberProfile whenever a MemberPayment is added to that MemberProfile.
MemberProfiles = new Mongo.Collection('memberProfiles');
MemberProfileSchema = new SimpleSchema({
expiryDate: {
type: Date,
autoValue: function () {
return moment().toDate();
},
autoform: {
type: "hidden"
}
}
// to insert into Memb erProfiles
{{> quickForm collection="MemberProfiles" id="insertMemberProfileForm" type="insert" class="new-recipe-form"}}
//the code for MemberPayments collection
MemberPayments = new Mongo.Collection('memberPayments');
MemberPayments.before.insert(function (userId, doc) {
let memberProfile= MemberProfiles.direct.findOne({profile: doc.memberId});
MemberProfiles.update(doc.memberId, {
$set: {
expiryDate: moment().add(31, 'days');
,
}
}
)
});
I have added all the necessary packages but still this doesnt work.I am getting error Cannot set property 'expiryDate' of undefined
It is challenging to try and resolve issues like this without having a more complete example of the app or reference to the complete project in github or somewhere else.
However, when I read through your code I noticed an issue in your MemberProfiles.update()
function. I also noticed that it appears you are only processing your form from the client side (e.g. because your quickform is not using a Meteor Method) so you will have to manually call the SimpleSchema .clean()
method to generate your autovalue. Keep in mind that your client side approach might work ok now, but once you remove the insecure
package you will either have to implement a Meteor Method to perform the insert or configure your collection allow/deny rules to allow client side insert (this is dangerous).
Since you are using moment.js
you need to be careful that you always pull the date from the moment object before storing in mongodb. In this case, you are trying to set expiryDate
to the value returned from moment().add(31, 'days')
which is just another moment object.
Also, I would assume you want to add 31 days to the current value of expiryDate, however you are never initializing moment with the expiryDate. Therefore, you will always be setting the expiryDate to 31 days from the time the function executes.
Lastly, you have a syntax error (;
inside your $set
object) and your findOne
selector includes {profile: doc.memberId}
however your MemberProfiles schema says there is only a _id
and expiryDate
field in your collection.
Try this new logic that addresses the above issues and see if that resolves your issue.
MemberPayments.before.insert(function (userId, doc) {
let memberProfile = MemberProfiles.direct.findOne({profile: doc.memberId});
if (memberProfile) {
if (!memberProfile.expiryDate) {
console.log("expiryDate was not previously set!");
} else {
MemberProfiles.update({profile: doc.memberId}, {
$set: {
expiryDate: moment(memberProfile.expiryDate).add(31, 'days').toDate()
}
});
}
} else {
console.log("memberProfile not found");
}
});
Now that this is fixed, you need to resolve the issue of your autovalue not being generated on the client side. You do this by calling the SimpleSchema .clean()
method. Since you are not using Meteor Methods to process your quickForm (and therefore doing everything client side), you need to add the below AutoForm hook to ensure that the SimpleSchema .clean()
method is called before the doc is saved (which will then execute your autovalue
logic).
AutoForm.hooks({
insertMemberProfileForm: {
before: {
insert: function(doc) {
MemberProfileSchema.simpleSchema().clean(doc);
return doc;
}
}
}
});
You should put the above code in the onRendered()
callback of the template that creates your quickform (e.g. the template that contains the below code in the HTML).
{{> quickForm collection="MemberProfiles" id="insertMemberProfileForm" type="insert" class="new-recipe-form"}}