Meteor aldeed/meteor-collection2 autoValue throwing error - meteor

I am trying to use autoValue in my schema
Posts.schema = new SimpleSchema({
title: { type: String },
description: { type: String },
posted: { type: Date,
autoValue: function (){
return new Date;
},
},
likes: { type: Number, defaultValue: 0, optional: true },
dislikes: { type: Number, defaultValue: 0, optional: true, },
author: { type: AuthorSchema },
votes: { type: [AuthorSchema], optional: true }
});
Posts.attachSchema(Posts.schema);
I am using this schema for validations here:
export const addPost = new ValidatedMethod({
name: 'Posts.addPost',
validate: Posts.schema.validator(),
run(post) {
if (!this.userId)
throw new Meteor.Error('403', 'You must be logged-in to reply');
Posts.simpleSchema().clean(post);
Posts.insert({
title: post.title,
description: post.description,
author: {
userId: this.userId,
vote: 0
}
});
}
});
It does not work. I get an error message
Posted is required [validation-error]
Am i doing something wrong? Do i need to make Posted field optional?
I tried to change the insert method by providing default value for posted: new Date(). Did not work either. Please help.

Fixed it by calling validator with { clean : true, filter : false }

Related

Aldeed Simple-Schema, how to use allowed values in a field from another one?

I am trying to build a kind of specific simple schema for a collection and i would like to make sure that :
when the user enter a new select in my selectsCollection, he will put one of the options value as selected value.
For example:
SelectsCollection.insert({name:"SelectOne",deviceType:"Select",options:["option1","option2","option3"],value:"option4",description:"This is the first select"});
this do not have to work. I want him to write only one of the 3 options.
Here my schema :
SelectsCollection = new Mongo.Collection('Selects'); //Create a table
SelectsSchema = new SimpleSchema({
name:{
type: String,
label:"Name",
unique:true
},
deviceType:{
type: String,
allowedValues: ['Select'],
label:"Type of Device"
},
options:{
type: [String],
minCount:2,
maxcount:5,
label:"Select Values"
},
value:{
type: String,
//allowedValues:[options] a kind of syntax
// or allowedValues:function(){ // some instructions to retrieve the array of string of the option field ?}
label:"Selected Value"
},
description:{
type: String,
label:"Description"
},
createdAt:{
type: Date,
label:"Created At",
autoValue: function(){
return new Date()
}
}
});
SelectsCollection.attachSchema(SelectsSchema);
Any Idea ? :)
Thanks a lot !
This could be done with custom validation function of a field, inside this function you could retrieve values from other fields:
SelectsSchema = new SimpleSchema({
// ...
options: {
type: [String],
minCount: 2,
maxcount: 5,
label: "Select Values"
},
value: {
label: "Selected Value",
type: String,
optional: true,
custom() {
const options = this.field('options').value
const value = this.value
if (!value) {
return 'required'
}
if (options.indexOf(value) === -1) {
return 'notAllowed'
}
}
},
// ...
});
Look here custom-field-validation for more information

Difference between defaultValue and autoValue in Autoform?

I'm working on a project which I start with using autoValue as
Programs.attachSchema(new SimpleSchema({
createdBy: {
type: String,
autoValue: function() {
return this.userId
},
optional: true,
autoform: {
type: 'hidden'
}
},
createdAt: {
type: Date,
label: "Created At",
defaultValue: new Date(),
optional: true,
autoform: {
type: 'hidden'
}
}
}));
everything works find until I need to update the information by other users, let's say admin, Programs.update or Programs.insert methods will change the email field.
I tried to use defaultValue for createdBy field but
defaultValue: this.userId
return me null
and i'm not allowed to use
defaultValue: Meteor.userId()
Can anyone explain the difference? I tried use function() {return this.userId} for defaultValue which still got no luck
defaultValue is used by simple-schema for defining default value. There are some quirks so read the docs: https://github.com/aldeed/meteor-simple-schema#defaultvalue
Think of when the code is ran and you will understand why you can't use Meteor.userId() or this.userId for defaultValue. The schema is ran once at startup.
What allows autoValue to work is that it returns a function. The function is ran during db updates/inserts. Read over the docs to fully understand it: https://github.com/aldeed/meteor-simple-schema#autovalue
Now, if I understand your question properly, you have issues with autoValue when an admin comes along and modifies the document? Causing the createdBy to be set to the admin's id? To solve something like that, you just need to be more specific with your autoValue function.
See if this code helps guide you in the proper direction:
Programs.attachSchema(new SimpleSchema({
createdBy: {
type: String,
autoValue: function() {
if (this.isInsert) {
return this.userId;
} else if (this.isUpsert) {
return { $setOnInsert: this.userId };
}
this.unset(); // Prevent user from supplying their own value
return undefined;
},
optional: true,
autoform: {
type: 'hidden'
}
},
createdAt: {
type: Date,
label: 'Created At',
defaultValue: new Date(),
optional: true,
autoform: {
type: 'hidden'
},
autoValue: function() {
if (this.isInsert) {
return new Date();
} else if (this.isUpsert) {
return { $setOnInsert: new Date() };
}
this.unset(); // Prevent user from supplying their own value
return undefined;
},
}
}));
You should try this snippet,
new SimpleSchema({
// ...
createdBy: {
autoValue() {
return Meteor.userdId();
}
}
// ...
})
Now the explanation, Your problem is more likely related with the this binding, this.userId, was called from SimpleSchema context in this way this does not have any userId() method, you should use the full namespace in this case Meteor.userId();
A very cool explanation on this binding I recommend you to read
This binding

datepicker value is getting clear when addon button is clicked

Here is code used in simpleschema definition.I tried to use the similar one in my project but as you can see it is not working.
{
items:{
type: Array,
optional: true,
minCount: 0,
maxCount: 5
},
"items.$": {
type: Object,
optional: true
},
"items.$.name": {
type: Date,
optional: true,
autoform: {
afFieldInput: {
type: "bootstrap-datetimepicker"
}
}
}
}
I was facing the issue because of some bug in autoform-datetimepicker Api.
I added the following line of code under autoform-bs-datepicker.js
`
this.autorun(function () {
var data = Template.currentData();
**if(!data.value)
data.value=$('#'+data.atts.id).val();**`

How to validate an update against SimpleSchema before updating a document in collection

I'm trying to validate my data against a SimpleSchema before it gets submitted to the collection but for some reason I'm not able to do so with this error.
Exception while invoking method 'createVendorCategory' { stack: 'TypeError: Cannot call method \'simpleSchema\' of undefined
I have one collections with two SimpleSchemas as follows.
Vendors = new Mongo.Collection('vendors'); //Define the collection.
VendorCategoriesSchema = new SimpleSchema({
name: {
type: String,
label: "Category"
},
slug: {
type: String,
label: "Slug"
},
createdAt : {
type: Date,
label: "Created At",
autoValue: function(){
return new Date()//return the current date timestamp to the schema
}
}
});
VendorSchema = new SimpleSchema({
name: {
type: String,
label: "Name"
},
phone: {
type: String,
label: "Phone"
},
vendorCategories:{
type: [VendorCategoriesSchema],
optional: true
}
});
Vendors.attachSchema(VendorSchema);
The vendorCategory will be added after the Vendor document is created by the user.
Here is what my client side looks like.
Template.addCategory.events({
'click #app-vendor-category-submit': function(e,t){
var category = {
vendorID: Session.get("currentViewingVendor"),
name: $.trim(t.find('#app-cat-name').value),
slug: $.trim(t.find('#app-cat-slug').value),
};
Meteor.call('createVendorCategory', category, function(error) {
//Server-side validation
if (error) {
alert(error);
}
});
}
});
And here is what my server side Meteor.methods look like
createVendorCategory: function(category)
{
var vendorID = Vendors.findOne(category.vendorID);
if(!vendorID){
throw new Meteor.Error(403, 'This Vendor is not found!');
}
//build the arr to be passed to collection
var vendorCategories = {
name: category.name,
slug: category.slug
}
var isValid = check( vendorCategories, VendorSchema.vendorCategories.simpleSchema());//This is not working?
if(isValid){
Vendors.update(VendorID, vendorCategories);
// return vendorReview;
console.log(vendorCategories);
}
else{
throw new Meteor.Error(403, 'Data is not valid');
}
}
I'm guessing this is where the error is coming from.
var isValid = check( vendorCategories, VendorSchema.vendorCategories.simpleSchema());//This is not working?
Any help would be greatly appreciated.
Since you've already defined a sub-schema for the sub-object you can directly check against that:
check(vendorCategories,VendorCategoriesSchema)

meteor - How to add a subdocument as reference with SimpleSchema

I have the following SimpleSchema
Schema.Team = new SimpleSchema({
name:{
type:String
},
members: {
type: [Schema.User],
optional:true
}
});
I would like to insert (on the server) a new team document with the current user, as a reference (not as an embedded document).
I have tried:
Teams.insert({name:"theName",members:[Meteor.user()]}) // works but insert the user as an embedded doc.
Teams.insert({name:"theName",members:[Meteor.user()._id]}) // Error: 0 must be an object
I have also tried in two steps:
var id = Teams.insert({name:teamName});
Teams.update({ _id: id },{ $push: { 'users': Meteor.user()._id } });
Then I have another error I don't understand: Error: When the modifier option is true, validation object must have at least one operator
So how can I insert a document with a reference to another schema?
If you just want to store an array of userIds in your Team collection try:
Schema.Team = new SimpleSchema({
name:{
type:String
},
members: {
type: [String],
optional:true
}
});
Then
Teams.insert({ name: "theName", members: [Meteor.userId()] });
Should work. Later when you want to add an additional id you can just:
Teams.update({ _id: teamId },{ $addToSet: { members: Meteor.userId() }});
The following is probably the syntax you are after, assuming you are also using AutoForm.
If you are using collection2, you can also add an autovalue for when a team is created to automatically add the creator to that team for more convenience.
Schema.Team = new SimpleSchema({
name: {
type:String
},
members: {
type: [String],
defaultValue: [],
allowedValues: function () {
// only allow references to the user collection.
return Meteor.users.find().map(function (doc) {
return doc._id
});
},
autoform: {
// if using autoform, this will display their username as the option instead of their id.
options: function () {
return Meteor.users.find().map(function (doc) {
return {
value: doc._id,
label: doc.username // or something
}
})
}
},
autoValue: function () {
if (this.isInsert && !this.isFromTrustedCode) {
return [this.userId];
}
}
}
});

Resources