Meteor User Accounts - OnSignin - meteor

I've changed my schema to include sub-schemas. I want to group relevant data together and make it easier to manage. Unfortanly this has broken my registration process. How do I make the autoform insert firstName into the sub-schema. Any thoughts?
Path: at_config.js
AccountsTemplates.addFields([
{
_id: "details.firstName",
type: 'text',
displayName: "First name",
required: true,
minLength: 1,
maxLength: 37
}
]);
Path: Schema.js
AccountsTemplates.configure({
Schema.UserDetails = new SimpleSchema({
firstName: {
type: String,
optional: false
}
});
Schema.UserProfile = new SimpleSchema({
details: {
type: Schema.UserDetails,
optional: true
},
});
Schema.User = new SimpleSchema({
profile: {
type: Schema.UserProfile,
optional: true
}
});
Meteor.users.attachSchema(Schema.User);
Path: startup.js
Accounts.onCreateUser(function (options, user) {
if (options.profile && options.profile.roles) {
//include the user profile
Roles.setRolesOnUserObj(user, options.profile.roles);
}
if (options.profile) {
// include the user profile
user.profile = options.profile;
}
return user;
});

Related

Combining simple schema errors

I'm trying to combine fields using simple schema. It works for Schema.UserProfile however it doesn't work for Schema.accountStatus.
If I try and populate the field when I create a new account it errors. Any thoughts on why, would really help, thanks?
Path: schemas.js
Schema = {};
Schema.accountStatus = new SimpleSchema({
isUserAccountActive: {
type: Boolean,
optional: true
},
startDate: {
type: Date,
optional: true
},
endDate: {
type: Date,
optional: true
}
});
Schema.UserProfile = new SimpleSchema({
firstName: {
type: String,
optional: false
},
lastName: {
type: String,
optional: true
},
});
Schema.User = new SimpleSchema({
profile: {
type: Schema.UserProfile,
optional: true
},
// Make sure this services field is in your schema if you're using any of the accounts packages
services: {
type: Object,
optional: true,
blackbox: true
},
accountStatus: {
type: Schema.accountStatus,
optional: true
},
// In order to avoid an 'Exception in setInterval callback' from Meteor
heartbeat: {
type: Date,
optional: true
}
});
Meteor.users.attachSchema(Schema.User);
Path: startup.js
Meteor.startup(function () {
console.log('Running server startup code...');
Accounts.onCreateUser(function (options, user) {
if (options.profile && options.profile.roles) {
//include the user profile
Roles.setRolesOnUserObj(user, options.profile.roles);
}
if (options.profile) {
// include the user profile
user.profile = options.profile;
}
// other user object changes...
// ...
user.isUserAccountActive = false;
return user;
});
});
I see now: isUserAccountActive is a sub-key of accountStatus. Change:
user.isUserAccountActive = false;
to
user.accountStatus = { isUserAccountActive: false };
Not clear why that should yield a server error though, perhaps it's because you're doing this update on the server side.

Accessing nested array in autoform hook

I have a collection that looks like this:
"request":{
type: [Object],
optional: true,
autoValue: function() {
var input = this.field('requestInput');
var type = this.field('requestTypeInput');
var emailTo = this.field('emailToInput');
var direction = this.field('directionInput');
var d = new Date;
//var requestFiles = this.field('requestFiles');
//console.log(requestFiles.value);
if(!!input.value){
if(this.isInsert){
return [{
"_id":Random.id(),
date: new Date(),
type: type.value,
details: input.value,
emailTo: emailTo.value,
direction : direction.value,
// requestFiles: requestFiles.value,
createdBy: this.userId
}];
} else {
return {
$push: {
"_id":Random.id(),
date: new Date(),
type: type.value,
details: input.value,
emailTo: emailTo.value,
direction : direction.value,
// requestFiles: requestFiles.value,
createdBy: this.userId
}
};
}
} else {
this.unset();
}
}
},
'request.$.date': {
type: Date,
optional: true
},
'request.$.details': {
type: String,
optional: true
},
'request.$.createdBy':{
type: String,
optional: true
},
"request.$.type":{
type: String
},
"request.$._id":{
type: String
},
"request.$.emailTo":{
type: String,
max: 1000,
optional: true
},
"request.$.direction":{
type: String,
max: 1000,
optional: true
},
"request.$.requestFiles":{
type: [String],
optional: true
}
What i want to do is use a before hook to set the value of the requestFiles but i cannot access it. This is what I have so far:
before:{
"method-update": function(doc) {
doc.$set.request.requestFiles = arrayOfFiles.list();
return doc;
}
}
this is telling me :
Uncaught TypeError: Cannot set property 'requestFiles' of undefined.
I have also tried:
doc.$set.request.0.requestFiles = arrayOfFiles.list();
doc.$set.request[0].requestFiles = arrayOfFiles.list();
I just want to pass that array value. If there is another solution to passing that value i will accept it.

Error when updating an object in auto-form with meteor

I have checked the docs but I cannot get my head around this. I have an object that I want to update using Auto-Form and Collections2 with meteor.
//Schema
Records = new Mongo.Collection('records');
var Schemas = {};
Schemas.Record = new SimpleSchema({
title: {
type: String,
label: "Title",
max: 200
},
caption: {
type: String,
label: "Caption",
max: 200
},
text: {
type: String,
label: "Detailed text",
optional: true,
max: 1000
},
loc: {
type: Object,
optional: true,
blackbox: true
},
createdAt: {
type: Date,
autoform: {
type: "hidden"
},
autoValue: function() {
if (this.isInsert) {
return new Date;
}
else if (this.isUpsert) {
return {
$setOnInsert: new Date
};
}
else {
this.unset();
}
}
},
updatedBy: {
type: String,
autoValue: function() {
return Meteor.userId();
}
}
});
Records.attachSchema(Schemas.Record);
I have a hook so that I assign the object before update
AutoForm.hooks({
insertCommentForm: {
before: {
insert: function(doc) {
doc.commentOn = Template.parentData()._id;
return doc;
}
}
},
updateRecordForm: {
before: {
update: function(doc) {
console.log("storing location data");
doc.loc = Session.get('geoData');
console.log(doc.loc);
return doc;
}
}
}
});
I get this error.
Uncaught Error: When the modifier option is true, all validation
object keys must be operators. Did you forget $set?
I don't know how to "$set" with autoform.
when you are trying to update a document in Mongo, when you want to update only certain fields, you will use the $set modifier.
Records.update({ _id: 1 }, { $set: { loc: { lat: 12, lng: 75 } } })
The above would update only the loc value.
Records.update({ _id: 1 }, { loc: { lat: 12, lng: 75 } })
The above would remove all other keys and the record will only have the _id and the loc.
Your hook will have to set the loc key in doc.$set.
Please update your hook with the following code and it should work:
updateRecordForm: {
before: {
update: function(doc) {
console.log("storing location data", doc);
doc.$set.loc = Session.get('geoData');
return doc;
}
}
}

Apply certain autovalue keys to all SimpleSchemas

I have certain keys such as createdAt and updatedAt that should be defined in all schemas. Is there a way to avoid code duplication?
I use the SimpleSchema package.
I need the following code in all of my Schemas.xxx
createdAt: {
type: Date,
optional: true,
autoValue: function() {
if (this.isInsert) {
return new Date;
} else if (this.isUpsert) {
return {$setOnInsert: new Date};
} else {
this.unset();
}
},
autoform: {
type: 'hidden'
}
},
updatedAt: {
type: Date,
optional: true,
autoValue: function() {
if (this.isUpdate) {
return new Date();
}
},
autoform: {
type: 'hidden'
}
}
Create a sub schema & then include it in every collection, notice the SimpleSchema constructor is now taking an array.
Schema._Basic = new SimpleSchema({
userId: {
type: String,
optional: true
},
createdAt: {
type: Date,
label: 'Created at'
},
updatedAt: {
type: Date,
label: 'Updated at',
optional: true
},
}
});
Schema.Client = new SimpleSchema([Schema._Basic,
{
address: {
type: String
optional: true
}
}
]);
I would do that with help of this very nice package: matb33:collection-hooks This will add before and after hooks to your collections. So you can add createdAt and updatedAt fields like this:
For CollectionName.insert();
CollectionName.before.insert(function (userId, doc) {
var currentDate = new Date();
doc.createdAt = currentDate;
doc.updatedAt = currentDate; // could be also null if you want
});
So that in above exmaple is triggered always just before the insert takes effect. And this is for CollectionName.update();
CollectionName.before.update(function (userId, doc) {
doc.updatedAt = new Date();
});
This is triggered whenever you update your collection.

How to add/edit users with meteor accounts and autoform

I am building part of an admin system in Meteor that lets admins add/edit other admins. I am using Meteor Accounts and Autoform, but I can't figure out how to handle it so the users are validated with Autoform and saved properly. From what i've found it looks like I need to use the Accounts.createUser method and make the form a type="method" or something, but I'm not sure how to handle that or if that is even the correct way.
Here is my code right now:
Schema:
Schema = {};
Schema.UserProfile = new SimpleSchema({
name: {
type: String,
label: "Name"
}
});
Schema.User = new SimpleSchema({
email: {
type: String,
regEx: SimpleSchema.RegEx.Email
},
password: {
type: String,
label: "Password",
min: 6
},
passwordConfirmation: {
type: String,
min: 6,
label: "Password Confirmation",
custom: function() {
if (this.value !== this.field('password').value) {
return "passwordMissmatch";
}
}
},
createdAt: {
type: Date,
autoValue: function() {
if (this.isInsert) {
return new Date;
} else if (this.isUpsert) {
return {$setOnInsert: new Date};
} else {
this.unset();
}
}
},
profile: {
type: Schema.UserProfile
},
services: {
type: Object,
optional: true,
blackbox: false
}
});
Meteor.users.attachSchema(Schema.User);
Routes:
Router.route('/admin/admins', {
controller: 'AdminController',
name: 'adminAdmins',
title: 'Admins',
parent: 'adminHome',
});
Router.route('/admin/admins/new', {
controller: 'AdminController',
name: 'adminAdminNew',
title: 'New Admin',
parent: 'adminAdmins',
});
Router.route('/admin/admins/:_id/edit', {
controller: 'AdminController',
name: 'adminAdminEdit',
title: 'Edit Admin',
parent: 'adminAdmins',
data: function() {
return Meteor.users.findOne(this.params._id);
}
});
Admin Form:
{{#autoForm collection="Meteor.users" doc=this id="adminAdminForm" type=formType}}
{{> afQuickField name='profile.name'}}
{{> afQuickField name='email'}}
{{> afQuickField name='password'}}
{{> afQuickField name='passwordConfirmation'}}
<button type="submit" class="btn btn-block btn-secondary">Save Changes</button>
{{/autoForm}}
You should add Hooks to be able to modify the collection
Something that should look like this
AutoForm.hooks({
adminAdminForm: {
onSubmit: function (doc) {
schemas.User.clean(doc);
this.done();
return false;
},
onSuccess:function(operation, result, template){
Router.go('users.show',{'username':template.data.doc.username});
},
onError: function(operation, error, template) {
console.log(operation,error)
}
}
});
You can find more details on the dedicated documentation https://github.com/aldeed/meteor-autoform#callbackshooks

Resources