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>
Related
I am using meteor autoform and iron:router to create a form that redirects to the form _id on submit (i.e localhost3000/submit/_id. That all works great but what I want to do now is make it so my template only displays that forms results not all of them.
here is the code I currently have
HTML:
<div class="displayBox">
{{#each Submits}}
{{> formDisplay}}
{{/each}}
</div>
<template name="formDisplay">
<h1>
{{title}}
{{subject}}
{{summary}}
</h1>
</template>
Hook:
AutoForm.addHooks('insertSubmit', {
onSuccess: function(doc) {
Router.go('formDisplay',{_id: this.docId});
}
})
Routing:
Router.route('/submit', {
layoutTemplate: 'submitLayout',
waitOn: function() { return Meteor.subscribe("Submits"); },
loadingTemplate: 'loading'
});
Router.route('/submit/:_id', {
name: 'formDisplay',
data: function() { return Products.findOne(this.params._id);},
waitOn: function() { return Meteor.subscribe("Submits"); },
loadingTemplate: 'loading'
});
Form:
SubmitSchema = new SimpleSchema({
title: {
type: String,
label: "Title"
},
subject:{
type: String,
label: "subject"
},
summary:{
type: String,
label: "Summary"
},
author:{
type: String,
label: "Author",
autoValue: function() {
return this.userId
},
autoform: {
type: "hidden"
}
},
createdAt: {
type: Date,
label: "Created At",
autoValue: function(){
return new Date()
},
autoform: {
type: "hidden"
}
}
});
Submits.attachSchema( SubmitSchema );
You need to add a id filter into your publication which only return you the current specific doc.
Your route code:
Router.route('/submit/:_id', {
name: 'formDisplay',
data: function() { return Products.findOne(this.params._id);},
waitOn: function() { return Meteor.subscribe("Submits", { '_id': this.params._id } ); },
loadingTemplate: 'loading'
});
Your publication code :
Meteor.publish('tasks', function(filter) {
filter = ( filter ? filter : {} );
return Products.findOne(filter);
});
I have the following schema:
GuestSchema = new SimpleSchema({
name: {
type: String,
label: 'Name'
}
code: {
type: String,
label: 'Code',
autoValue: function(){
return AutoForm.getFieldValue('name', 'insertGuestForm');
},
autoform: {
type: 'hidden'
}
}
});
<template name="NewGuest">
<div class="new-guest">
{{> quickForm collection="Guests" id="insertGuestForm" type="insert" class="new-guest-form"}}
</div>
</template>
but AutoForm.getFieldValue isn't working as expected. I want to get the field value of name and save it with the property code in my DB.
ok, I have to use this.field("name");
GuestSchema = new SimpleSchema({
name: {
type: String,
label: 'Name'
}
code: {
type: String,
label: 'Code',
autoValue: function(){
var content = this.field("name");
return content.value;
},
autoform: {
type: 'hidden'
}
}
});
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;
}
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 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.