I have an insert form which is created using autoform, collection2 and simple schema. The createdBy field is populated with the userId using autovalue. The form worked when using meteor.allow() for the insert but I wanted to replace the allow with a method so that I can do some validating of user roles ie make sure the user has admin rights. But now I get an error that the createdBy field is empty.
The error in dev tools is:
error: 400, reason: "Created by is required", details: undefined,
message: "Created by is required [400]", errorType: "Meteor.Error"}
Courses = new Mongo.Collection('Courses');
courseSchema = new SimpleSchema({
title: {
type: String,
label: "Course Title"
},
description: {
type: String,
label: "Description"
},
createdAt: {
type: Date,
autoValue: function(){
return new Date();
},
autoform:{
type: 'hidden'
}
},
startDate:{
type: String,
label: "Start Date"
},
sessions: {
type: String,
label: "No. of sessions"
},
duration: {
type: String,
label: "Duration of the course"
},
price: {
type: String,
label: "Course Price"
},
createdBy:{
type: String,
autoValue:function(){
return this.userId;
},
autoform:{
type:'hidden'
}
}
});
Courses.attachSchema(courseSchema);
The method (which is available on the client and the server):
Meteor.methods({
addCourse: function(course){
Courses.insert(course);
}
});
And the template where the form is generated:
<template name="adminIndex">
<h1>Available Courses</h1>
{{> courseList }}
<button type="button" class="btn btn-success btn-block">Create New Course</button>
<h3>Create New Course</h3>
{{>quickForm id="InsertCourseForm" collection="Courses" type="method" meteormethod="addCourse"}}
</template>
You need to clean the object by calling Courses.simpleSchema().clean(course); in the server method in order to add auto and default values securely. Also, please note that this.userId in your autoValue function is null for server-initiated actions, so you probably want to replace it with Meteor.userId().
In addition, you must perform your own validation by calling check(value, pattern) in the Meteor method, because client side validation can be bypassed.
For example:
if (Meteor.isServer) {
Meteor.methods({
addCourse: function(course) {
Courses.simpleSchema().clean(course);
check(course, Courses.simpleSchema());
Courses.insert(course);
}
});
}
So this worked but I haven't seen it used in any other examples so I have a bad feeling, but until I can find out more it will have to do:
createdBy:{
type: String,
autoValue:function(){
if(Meteor.isClient){
return this.userId;
}else if(Meteor.isServer){
return Meteor.userId();
}
},
Related
im doing the "Intermediate Meteor Tutorial #8 - Insert Permissions, Publishing & Meteor Toys" by LevelUpTuts and my problem is that i cant submit the form i checked the code 5 times but in my opinion everything is right im running meteor 1.4 here is my code
my Recipes.js file
Recipes = new Meteor.Collection('recipes');
Recipes.allow({
insert: function(userId, doc) {
return !!userId;
}
});
RecipeSchema = new SimpleSchema ({
name: {
type: String,
label: "Name"
},
desc: {
type: String,
label: "Description"
},
author: {
type: String,
label: "Author",
autoValue: function() {
return this.userID
},
autoform: {
type: "hidden"
},
},
createdAt: {
type: Date,
label: "CreatedAt",
autoValue: function() {
return new Date()
},
autoform: {
type: "hidden"
},
},
});
Recipes.attachSchema( RecipeSchema);
my recipes.js
Meteor.subscribe('recipes');
my NewRecipe.js
<template name="NewRecipe">
<div class="new-recipe-container">
{{> quickForm collection="Recipes" id="insertRecipeForm" type="insert" class="new-recipe-form"}}
</div>
</template>
and the publis.js file
Meteor.publish('recipes', function(){
return Recipes.find({author: this.userId});
});
Please help me i dont know what i am doing wrong
i don't have the answer for you (at least not yet), but i'm posting this as an answer so i can provide some formatted code.
you posted some code under NewRecipe.js, but i assume that view code is in NewRecipe.html. Try 2 things:
first, put this code in NewRecipe.js onCreated():
SimpleSchema.debug = true;
AutoForm.addHooks(null, {
onError: function(name, error, template) {
console.log(name + " error:", error);
}
});
that will enable some debugging for the quickform.
second, in the schema definition, comment out the Recipes.allow() block to see if that's what's blocking saving your data.
then report back on how that goes.
I am trying to insert a document into my meteor collection with an autoform made from my mongo schema, yet when I press the submit button it is giving me a "method not found [404]" error in the dev console. I believe it is coming from this code:
GameList.allow({
insert: function(userId, doc){
return !!userId;
}
});
which allows people to add documents to the database if they are logged in as a user. Without this code I will receive a "not authorized [403]" error, because I took out the insecure package from my meteor app. Any idea on what is causing this method not found error?
Autoform code:
{{> quickForm collection="GameList" id="insertGameForm" type="insert" class="newGameForm"}}
Schema for autoform:
GameListSchema = new SimpleSchema({
title: {
type: String,
label: "Title"
},
platform: {
type: String,
label: "Platform"
},
category: {
type: String,
label: "Category"
},
gameRank: {
type: String,
label: "GameRank"
},
auth: {
type: String,
label: "Author",
autoValue: function(){
return this.userId
},
autoform: {
type: "hidden"
}
}
});
GameList.attachSchema(GameListSchema);
I believe this is happening because your allow/deny rules are supposed to run on the server according to the Meteor documentation. Try putting them on server-side code and running this again.
I'm trying to customise my Meteor.users schema:
Schema.users = new SimpleSchema({
username: {
type: String,
},
test:{
type: String,
},
services: {
type: Object,
optional: true,
blackbox: true
}
});
And when I call:
Accounts.createUser({username:"lionel",test:"123",password:"123"});
Console returned:
Exception while invoking method 'createUser' Error: Test is required
......
Sanitized and reported to the client as: Test is required [400]
What am i missing here?
Accounts.createUser() expects extra info to come across in a profile key.
Use:
Accounts.createUser({username:"lionel",password:"123",profile: {test:"123"}});
And set up an Accounts.onCreateUser() function on the server:
Accounts.onCreateUser(function(options, user) {
if (options.profile) user.test = options.profile.test;
return user;
});
docs
I'm trying to create a Meteor method to save the user profile from a form created by autoform. I'm getting an error saying the userSchema is not defined. It is defined in my helper which is within a Meteor.isClient condition, which could be the problem. I tried making it available to both the client and server but that didn't work.
What I'm trying to acheive is simply take the form values and insert them into the Meteor.users.profile.
Looks like the server isn't seeing the userSchema which is visible on the client.
I'm getting this error:
I20140816-14:14:28.170(-7)? Exception while invoking method 'saveProfile' ReferenceError: userSchema is not defined
I20140816-14:14:28.173(-7)? at Meteor.methods.saveProfile (app/server/server.js:6:16)
I20140816-14:14:28.173(-7)? at maybeAuditArgumentChecks (packages/livedata/livedata_server.js:1487)
I20140816-14:14:28.173(-7)? at packages/livedata/livedata_server.js:643
I20140816-14:14:28.173(-7)? at _.extend.withValue (packages/meteor/dynamics_nodejs.js:56)
I20140816-14:14:28.174(-7)? at packages/livedata/livedata_server.js:642
I20140816-14:14:28.174(-7)? at _.extend.withValue (packages/meteor/dynamics_nodejs.js:56)
I20140816-14:14:28.176(-7)? at _.extend.protocol_handlers.method (packages/livedata/livedata_server.js:641)
I20140816-14:14:28.176(-7)? at packages/livedata/livedata_server.js:541
My Schema:
if (Meteor.isClient) {
Schema = {};
Schema.UserProfile = new SimpleSchema({
firstName: {
type: String,
regEx: /^[a-zA-Z-]{2,25}$/
},
lastName: {
type: String,
regEx: /^[a-zA-Z]{2,25}$/
},
gender: {
type: String,
allowedValues: ['Male', 'Female']
},
bio: {
type: String,
},
avatar: {
type: String,
},
pinCode: {
type: Number,
min: 7,
max: 7
},
phoneNumber: {
type: Number,
min: 9,
max: 10
}
});
Schema.User = new SimpleSchema({
_id: {
type: String,
regEx: SimpleSchema.RegEx.Id,
optional: true,
},
email: {
type: String,
regEx: SimpleSchema.RegEx.Email,
optional: true,
},
createdAt: {
type: Date,
optional: true
},
profile: {
type: Schema.UserProfile,
},
services: {
type: Object,
optional: true,
blackbox: false
}
});
SimpleSchema.debug = true;
Meteor.users.attachSchema(Schema.User);
}
Here's my helper:
Template.signupForm.helpers({
users: function () {
return Meteor.users;
},
userSchema: function () {
console.log('returning user schema')
console.log(Schema.User)
return Schema.User;
}
});
My Meteor method (server.js):
Meteor.methods({
saveProfile: function(doc) {
console.log('Meteor method 1')
// Important server-side check for security and data integrity
check(doc, userSchema);
console.log('Meteor method')
console.log(doc.firstName)
}
});
My template
<template name="signupForm">
<div class="panel-body">
{{#autoForm schema=userSchema id="signupForm" type="method" meteormethod="saveProfile"}}
<fieldset>
{{> afObjectField name='profile'}}
</fieldset>
<button type="submit" class="btn btn-primary">Insert</button>
{{/autoForm}}
</div>
</template>
Please apply 2 steps :
1 :
Add Schema object (wih all descendants) to dir (like folder both) where it will be visible for client and server.
2 :
On server side use Schema.User instead userSchema.
Note that userSchema is defined on client side in Template.signupForm.helpers and because of that Meteor.methods.saveProfile cannot find it.
I am using using collection2 and autoform with one level nested schemas
Node = new Meteor.Collection('node',{
schema: new SimpleSchema({
content: {
type: String,
label: "Content",
max: 200
}
created: {
type: Date,
label: "Created Date"
},
modified: {
type: Date,
label: "Modified Date"
}
})
});
NodeMeta = new Meteor.Collection('Node_meta',{
schema: new SimpleSchema({
desc:{
type:String,
max:200,
label:"Description",
optional:true
}
})
});
Schema = {};
Schema.nodeWithMeta= new SimpleSchema({
Node: {
type: Node.simpleSchema()
},
Meta: {
type: NodeMeta.simpleSchema()
}
});
{{#autoForm schema=schema id="nodeForm" type="method" meteormethod="nodecreate"}}
{{> afFieldInput name='Node.content' rows=8 }}
{{> afFieldInput name='Meta.desc' rows=8}}
<button type="submit" class="btn btn-primary btn-submit">Create</button>
{{/autoForm}}
Template.nodeCreate.helpers({
schema: function() {
return Schema.nodeWithMeta;
}
});
It does not call server method. I tried autoform onSubmit hook as well as Meteors inbuilt templates 'submit' event handler. If I use jQuery onsubmit event handler, it registers the event. I cannot use jQuery for this purpose since autoform has to validate the inputs.
Since created and modified are required fields, it's most likely not submitting because those fields are missing from the form, which means the form is invalid. There are actually a few different ways you can solve this:
Make them optional (probably not what you want)
Use a different schema, one without those two fields, for the schema attribute of the autoform.
Add a "before method" hook that sets those two fields in the submitted doc.
Use autoValue to generate the values for those two fields.
Since created and modified dates are fairly easy to do with autoValue, I would do it that way. Something like this:
created: {
type: Date,
label: "Created Date",
autoValue: function () {
if (this.isInsert) {
return new Date;
} else {
this.unset();
}
}
},
modified: {
type: Date,
label: "Modified Date",
autoValue: function () {
if (this.isInsert) {
this.unset();
} else {
return new Date;
}
}
}
Also, to help figure out issues like this more easily while developing, I recommend enabling debug mode.
Have you allowed inserts/updates on your collection? See http://docs.meteor.com/#dataandsecurity.
I bet if you run the two commands below, it'll work.
meteor add insecure
meteor add autopublish
Now try your submit.
If it does work, turn autopublish and insecure back off
meteor remove insecure
meteor remove autopublish
Then write your allow methods, e.g.
Node.allow({
insert: function (userId, nodeDoc) {
// write some logic to allow the insert
return true;
}
});