I am attempting nest an each statement to handle the two objects that are available within my view. There is a relationship between the two objects with the userId on the card as the connection to the userId on the user table, which might be how this could work. I figure that I might have to end up registering a helper to have this work, but I'm not sure where to start. I attempted to bypass this process with the following handlebars syntax, but I get TypeError: inverse is not a function:
{{#each this.fullNameSlug ../user.fullNameSlug}}
<h5>{{this.fullNameSlug}}</h5>
{{/each}}
Here is the full view:
{{#each card}}
<div class="row">
<div class="card col-md-6 col-md-offset-3">
<div class="card-date">
<p class="card-date">{{this.cardDateSlug}}</p>
</div>
<div class="card-header">
<h3 class="card-title">{{this.title}}</h3>
{{#each this.fullNameSlug ../user.fullNameSlug}}
<h5>{{this.fullNameSlug}}</h5>
{{/each}}
</div>
<div class="card-body">
{{/each}}
Here is the route with the two objects (card, user) that are accessible in the view:
/*==== / ====*/
appRoutes.route('/')
.get(function(req, res){
models.Card.findAll({
order: 'annotationDate DESC',
include: [{
model: models.User,
where: { organizationId: req.user.organizationId },
attributes: ['organizationId', 'userId', 'fullNameSlug']
}],
limit: limitAmount.limit
}).then(function(annotation){
res.render('pages/app/activity-feed.hbs',{
card: card,
user: req.user
});
});
})
Card object:
module.exports = function(sequelize, DataTypes) {
var path = require('path');
var moment = require('moment');
var Card = sequelize.define('card', {
cardId: {
type: DataTypes.INTEGER,
field: 'card_id',
autoIncrement: true,
primaryKey: true
},
cardDate: {
type: DataTypes.DATE,
field: 'card_date',
isDate: true
},
reportLink: {
type: DataTypes.TEXT,
field: 'report_link'
},
fileAttachment: {
type: DataTypes.STRING,
field: 'file_attachment'
},
userId: {
type: DataTypes.INTEGER,
field: 'user_id'
},
discoverySourceId: {
type: DataTypes.INTEGER,
field: 'discovery_source_id'
}
},
{
freezeTableName: true,
getterMethods: {
cardDateSlug: function(){
var date = new Date(this.getDataValue('annotationDate'));
var momentDate = moment(date).utc().format("MM/DD/YYYY");
return momentDate;
}
},
classMethods: {
associate: function(db) {
Card.belongsTo(db.User, {foreignKey: 'user_id'}),
}
}
});
return Card;
}
User object:
var bcrypt = require('bcrypt-nodejs');
module.exports = function(sequelize, DataTypes) {
var User = sequelize.define('user', {
userId: {
type: DataTypes.INTEGER,
field:'user_id',
autoIncrement: true,
primaryKey: true
},
firstName: {
type: DataTypes.STRING,
field: 'first_name'
},
lastName: {
type: DataTypes.STRING,
field: 'last_name'
},
email: {
type: DataTypes.STRING,
isEmail: true,
unique: true,
set: function(val) {
this.setDataValue('email', val.toLowerCase());
}
},
password: DataTypes.STRING,
organizationId: {
type: DataTypes.INTEGER,
field: 'organization_id',
allowNull: true
},
authenticationToken: {
type: DataTypes.STRING,
field: 'authentication_token'
},
resetPasswordToken: {
type: DataTypes.STRING,
field: 'reset_password_token'
},
resetPasswordExpires: {
type: DataTypes.DATE,
field: 'reset_password_expires'
}
}, {
freezeTableName: true,
getterMethods: {
fullNameSlug: function(){
var fullName = this.getDataValue('firstName') + ' ' + this.getDataValue('lastName');
return fullName;
}
},
classMethods: {
associate: function(db) {
User.belongsToMany(db.Organization, { through: 'member', foreignKey: 'user_id'})
},
generateHash: function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
},
},
instanceMethods: {
validPassword: function(password) {
return bcrypt.compareSync(password, this.password);
},
},
});
return User;
}
Related
I'm currently using lukemadera:autoform-googleplace to save the users address. When the user saves their address it only saves the fullAddress field in the schema. I thought it broke the address up into its parts; street, state, zip etc. That way you could publish the address parts individually if required. I would like to be able to publish just the state in certain circumstances but I'm not sure how to do that since all I have is a fullAddress field string. Let me know if you need more clarification.
Path: address.js
Template.address.helpers({
optsGoogleplace: function() {
return {
// type: 'googleUI',
// stopTimeoutOnKeyup: false,
googleOptions: {
componentRestrictions: { country:'au' }
}
}
},
});
Path: address.html
{{#autoForm collection="Meteor.users" id="user" doc=currentUser type="update"}}
{{> afQuickField name="profile.address" type="googleplace" opts=optsGoogleplace class="form-control"}}
{{autoForm}}
Path: Schema.js
Schema.Address = new SimpleSchema({
fullAddress: {
type: String
},
lat: {
type: Number,
decimal: true
},
lng: {
type: Number,
decimal: true
},
geometry: {
type: Object,
blackbox: true
},
placeId: {
type: String
},
street: {
type: String,
max: 100
},
city: {
type: String,
max: 50
},
state: {
type: String,
regEx: /^A[LKSZRAEP]|C[AOT]|D[EC]|F[LM]|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEHINOPST]|N[CDEHJMVY]|O[HKR]|P[ARW]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY]$/
},
zip: {
type: String,
regEx: /^[0-9]{5}$/
},
country: {
type: String
}
});
If you have it set up correctly, something like this should work:
Schemas = {};
Schemas.Address = new SimpleSchema({
fullAddress: {
type: String
},
lat: {
type: Number,
decimal: true
},
lng: {
type: Number,
decimal: true
},
geometry: {
type: Object,
blackbox: true
},
placeId: {
type: String
},
street: {
type: String,
max: 100
},
city: {
type: String,
max: 50
},
state: {
type: String,
},
zip: {
type: String,
},
country: {
type: String
},
});
Schemas.MainSchema = new SimpleSchema({
address: {
type: Schemas.Address,
optional: true
}
});
MainSchema = new Mongo.Collection("MainSchema");
MainSchema.attachSchema(Schemas.MainSchema);
MainSchema.allow({
insert: function () { return true; },
update: function () { return true; },
remove: function () { return true; }
});
Maybe check these out:
https://github.com/lukemadera/meteor-autoform-googleplace/issues/24
https://github.com/lukemadera/meteor-autoform-googleplace/issues/25
http://www.curtismlarson.com/blog/2015/12/11/meteor-location-search-engine-mongodb-google-maps/
My only other guess is something is wrong with you google options helper. I'm not using that right now and the above setup works for me.
I've installed lukemadera:autoform-googleplace package and followed the usage instructions. When I run the application the address field doesn't auto populate as I type. I get an error in console (Exception in template helper: ReferenceError: EJSON is not defined) can someone please tell me what I'm missing.
Path: Layout.html
<head>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?libraries=places"></script>
</head>
Path: Schema.js
Schema.Address = new SimpleSchema({
fullAddress: {
type: String
},
lat: {
type: Number,
decimal: true
},
lng: {
type: Number,
decimal: true
},
geometry: {
type: Object,
blackbox: true
},
placeId: {
type: String
},
street: {
type: String,
max: 100
},
city: {
type: String,
max: 50
},
state: {
type: String,
regEx: /^A[LKSZRAEP]|C[AOT]|D[EC]|F[LM]|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEHINOPST]|N[CDEHJMVY]|O[HKR]|P[ARW]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY]$/
},
zip: {
type: String,
regEx: /^[0-9]{5}$/
},
country: {
type: String
}
});
Schema.UserProfile = new SimpleSchema({
address: {
type: Schema.Address,
optional: true
}
});
Path: personalDetails.js
<template name="personalDetails">
{{#autoForm collection="Meteor.users" id="candidateProfile" doc=currentUser type="update"}}
{{> afQuickField name="profile.address" type="googleplace" opts=optsGoogleplace}}
{{/autoForm}}
</template>
Path: personalDetails.js
Template.personalDetails.helpers({
optsGoogleplace: function() {
return {
// type: 'googleUI',
// stopTimeoutOnKeyup: false,
// googleOptions: {
// componentRestrictions: { country:'us' }
// }
}
}
});
FYI, just in case someone else gets this error, you need to install ejson.
I'm new to Meteor and programming, if this doesn't make sense or you need more info please let me know.
I'm loading a profile page of another user. So I have 2 userIds; this.userId and the other users Id. I want to use autoValue to save both userIds when an action is taken. I can't figure out how to set the other users id even though I can display it on the html page.
Path: schema.js
Schemas.class = new SimpleSchema({
Title: {
type: String,
optional: true
},
teacherProfile: {
type: String,
optional: true,
autoValue: function() {
return this.userId
},
autoform: {
type: "hidden"
}
},
studentProfileId: {
type: String,
optional: true,
type: String,
autoform: {
defaultValue: "studentProfileId",
type: "hidden"
}
}
});
Path: profile.js
Template.teacherProfile.helpers({
studentProfile: ()=> {
var id = FlowRouter.getParam('id');
return Meteor.users.findOne({_id: id});
}
});
This is my solution it seems to work. Thanks to everyone that helped.
Path: schema.js
Schemas.class = new SimpleSchema({
Title: {
type: String,
optional: true
},
teacherProfile: {
type: String,
optional: true,
autoValue: function() {
return this.userId
},
autoform: {
type: "hidden"
}
},
studentProfileId: {
type: String,
optional: true,
autoform: {
type: "hidden"
}
}
});
Path: profile.js
Template.profile.helpers({
studentProfile: ()=> {
var id = FlowRouter.getParam('id');
return Meteor.users.findOne({_id: id});
},
studentProfileId: () => {
return FlowRouter.getParam('id');
}
)};
Path: profile.html
<template name="profile">
{{#autoForm collection="Jobs" id="Offer" type="insert"}}
{{> afQuickField name='Title'}}
{{> afQuickField name='studentUserId' value=studentProfileId}}
<button type="submit" class="btn btn-primary">Insert</button>
{{/autoForm}}
</template>
I am having problems with Collection2 and autoform. Here is my collection
Customers = new Mongo.Collection("customers");
Customers.allow({
insert: function(userId, doc) {
return !!userId;
}
});
CustomerSchema = new SimpleSchema({
name: {
type: String,
label: "Name"
},
address: {
type: String,
label: "Address"
},
amount: {
type: Number,
label: "Amount"
},
bvn: {
type: String,
label: "BVN"
},
type: {
type: String,
label: "Sale Type"
},
saleDate: {
type: Date,
label: "Transaction Date",
autoValue: function() {
return new Date()
},
autoform: {
type: "hidden"
}
},
passport: {
type: String,
label: "Passport Number"
},
source: {
type: String,
label: "Source"
},
tickets: {
type: Boolean,
label: "Tickets"
},
visa: {
type: Boolean,
label: "Visa"
},
invoice: {
type: Boolean,
label: "Invoice"
},
nextSaleDate: {
type: Date,
label: "Next Sale Date",
autoValue: function () {
var thisDate = new Date();
var dd = thisDate.getDate();
var mm = thisDate.getMonth() + 3;
var y = thisDate.getFullYear();
var nextDate = dd + '/'+ mm + '/'+ y;
return nextDate;
},
autoform: {
type: "hidden"
}
},
author: {
type: String,
label: "Author",
autoValue: function () {
return this.userId
},
autoform: {
type: "hidden"
}
}
});
Customers.attachSchema(CustomerSchema);
I have published and subscribed to the collections in separate publish and subscribe javascript files with methods Meteor.publish('customers', function() {
return Customers.find({author: this.userId});
}); and Meteor.subscribe("customers"); respectively. Here is the html code for insert
<template name="NewCustomer">
<div class="new-customer">
{{>quickForm collection="Customers" id="insertCustomerForm" type="insert" class="new-customer-form"}}
</div>
</template>
But when i bootup the server and add a new customer, it doesn't work. Can anyone help me out? Thank you
I sorted it out. This field in the collection
nextSaleDate: {
type: Date,
label: "Next Sale Date",
autoValue: function () {
var thisDate = new Date();
var dd = thisDate.getDate();
var mm = thisDate.getMonth() + 3;
var y = thisDate.getFullYear();
var nextDate = dd + '/'+ mm + '/'+ y;
return nextDate;
},
autoform: {
type: "hidden"
}
},
is the one causing the issue. Thank you all for your input
I have an app in which I'm using a template helper. I have the following code:
UI.registerHelper('ProfileNameByUserId', function(userid) {
console.log('Userid: ' + userid);
var user = Meteor.users.findOne({'_id': userid});
console.log.log('User:' + user);
return user.username
});
I'm calling this in my template as follows:
{{#each getDocuments}}
{{ProfileNameByUserId userid}}
{{/each}}
and in the template helper:
Template.documentsIndex.helpers({
getDocuments: function () {
return Documents.find({}, { sort: { createdAt: -1 }});
}
});
The publish and subscribe are as follows:
Routes.route('/documents', {
name: 'documents',
subscriptions: function (params, queryParams) {
this.register('documentsIndex', Meteor.subscribe('documents'));
},
action: function (params, queryParams) {
.....
});
}
});
Meteor.publish('documents', function () {
return Documents.find({})
});
I'm sure the userId is passed on, as a console.log statement shows the correct id. The issue is that the user is 'undefined' so it can't find the username.
I'm using SimpleSchema to define a users schema which looks as follows:
Users = Meteor.users;
Schema = {};
Schema.UserProfile = new SimpleSchema({
firstName: {
type: String,
optional: true
},
lastName: {
type: String,
optional: true
},
gender: {
type: String,
allowedValues: ['Male', 'Female'],
optional: true
},
});
Schema.User = new SimpleSchema({
username: {
type: String,
optional: true
},
emails: {
type: Array,
optional: true
},
"emails.$": {
type: Object
},
"emails.$.address": {
type: String,
regEx: SimpleSchema.RegEx.Email
},
"emails.$.verified": {
type: Boolean
},
createdAt: {
type: Date,
optional: true,
denyUpdate: true,
autoValue: function() {
if (this.isInsert) {
return new Date();
}
}
},
profile: {
type: Schema.UserProfile,
optional: true
},
services: {
type: Object,
optional: true,
blackbox: true
},
roles: {
type: [String],
optional: true
}
});
Meteor.users.attachSchema(Schema.User);
});
Replacing Meteor.users.findOne() in the template helper with Users.findOne() does not work either.
Any idea why user remains undefined?
You need to add a publication and subscription for the users that you want to show.
In the most general case in which all users are published:
Meteor.publish('allUsers', function () {
return Meteor.users.find();
});
Subscribe to this in your route and you will not have the user undefined in your helper.
Note that you should only publish the users that you need, but since I do not know you application structure I cannot give you a query for that.