PUT not working/saving data - javascript

I am trying to have it so that when a user clicks a checkbox that the value is true but when they leave it unchecked it goes to false. I want it so they default to true. I have the following as part of my user model.
Part of my user model:
newsletterEmail: { type: Boolean, default: 'true'},
lowerLimitEmail: { type: Boolean, default: 'true'},
featuresEmail: { type: Boolean, default: 'true'},
assetOut180: { type: Boolean, default: 'true'},
lowerLimit: { type: Boolean, default: 'true'},
The HTML I have for the checkbox is:
<div class="form-check">
<label class="form-check-label">
<input class="form-check-input" name="newsletterEmail" type="checkbox" value="true">
Newsletter notifications
</label>
</div>
Then inside my route I have this query:
User.findById(req.user.id, function(err, user) {
if (err) return (err);
user.newsletterEmail = req.body.newsletterEmail || false;
user.lowerLimitEmail = req.body.lowerLimitEmail || false;
user.featuresEmail = req.body.featuresEmail || false;
user.assetOut180 = req.body.assetOut180 || false;
user.lowerLimit = req.body.lowerLimit || false;
user.save(function(err) {
if (err) return (err);
req.flash('success', { msg: 'Notification Settings Updated.' });
res.redirect(req.redirect.success);
});
});
What is wrong? I took the code from another route and modified it to see if I just wrote the basic part of the route wrong, I that part right, so I am pretty sure is has to do with the query.

Related

Sending static data using bootstrapValidator locally

how to use a remote back-end to check if a given username is already taken or not.
check and validate locally without using database or web-server
This is latest version of bootstrapValidator, jquery, html5, bootstrap.
<script src="js/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery.bootstrapvalidator/0.5.2/js/bootstrapValidator.min.js"></script>
<form id="registrationForm" class="form-horizontal">
<div class="form-group">
<label class="col-lg-3 control-label">Username</label>
<div class="col-lg-5">
<input type="text" class="form-control" name="username" />
</div>
</div>
</form>
and custom js is
$(document).ready(function() {
$('#registrationForm').bootstrapValidator({
fields: {
username: {
message: 'The username is not valid',
validators: {
remote: {
message: 'The username is not available',
url: 'default.php',
data: {
type: 'username'
}
}
}
}
}
});
});
back-end default.php file is
<?php
$isAvailable = true;
switch ($_POST['type']) {
case 'username':
default:
$username = $_POST['username'];
data = 'admin','root';
$isAvailable = true;
break;
}
echo json_encode(array(
'valid' => $isAvailable,
));
username already exists or not from default.php file, error
not showing.
$(document).ready(function() {
$('#registrationForm').bootstrapValidator({
fields: {
username: {
message: 'The username is not valid',
validators: {
callback: {
callback: function(value, validator) {
var data = "user1";
if (value === data) {
return {
valid: false,
message: 'The name is not available'
}
}
return true;
}
}
}
}
}
});
});
Instead of using php function, I have used call back function for this it's working fine.

SequelizeJS Passing Array of Values

I am trying to figure out how it is possible to pass an array as the value for the property of an instance. I currently have the dataType set to STRING in my model and have values from jQuery fields insert each form field value into an array that I parse from the body and set to the property, discoverSource. Unfortunately I receive a string violation error that says I can't use an array or object. What does this mean and how can I change the dataType of the field or route to allow me to pass the comma separated values to the field?
E.x. For discoverySource I pass values to two fields (NJ, NY). On submit, the values are combined in an array as ["NJ", "NY"] and the error displays:
Error Message:
{"name":"SequelizeValidationError","message":"string violation: discoverySource cannot be an array or an object","errors":[{"message":"discoverySource cannot be an array or an object","type":"string violation","path":"discoverySource","value":["NJ","NY"]}]}
Here is my model:
module.exports = function(sequelize, DataTypes) {
var Organization = sequelize.define('organization', {
organizationId: {
type: DataTypes.INTEGER,
field: 'organization_id',
autoIncrement: true,
primaryKey: true
},
organizationName: {
type: DataTypes.STRING,
field: 'organization_name'
},
admin: DataTypes.STRING,
discoverySource: {
type: DataTypes.TEXT,
field: 'discovery_source'
},
members: DataTypes.STRING
},{
freezeTableName: true,
classMethods: {
associate: function(db) {
Organization.belongsToMany(db.User, { through: 'member', foreignKey: 'user_id' });
},
},
});
return Organization;
}
Here is the route:
var express = require('express');
var appRoutes = express.Router();
var passport = require('passport');
var localStrategy = require('passport-local').Strategy;
var models = require('../models/db-index');
appRoutes.route('/sign-up/organization')
.get(function(req, res){
models.User.find({
where: {
user_id: req.user.email
}, attributes: [ 'user_id', 'email'
]
}).then(function(user){
res.render('pages/app/sign-up-organization.hbs',{
user: req.user
});
})
})
.post(function(req, res, user){
models.Organization.create({
organizationName: req.body.organizationName,
admin: req.body.admin,
discoverySource: req.body.discoverySource
}).then(function(organization, user){
res.redirect('/app');
}).catch(function(error){
res.send(error);
console.log('Error at Post' + error);
})
});
Here is my view file:
<!DOCTYPE html>
<head>
{{> head}}
</head>
<body>
{{> navigation}}
<div class="container">
<div class="col-md-6 col-md-offset-3">
<form action="/app/sign-up/organization" method="post">
<p>{{user.email}}</p>
<input type="hidden" name="admin" value="{{user.email}}">
<input type="hidden" name="organizationId">
<label for="sign-up-organization">Company/Organization Name</label>
<input type="text" class="form-control" id="sign-up-organization" name="organizationName" value="" placeholder="Company/Organization">
Add Another Discovery Source
<div id="sign-up-organization-discovery-source">
<input type="text" id="discovery-source-field" placeholder="Discovery Source" name="discoverySource[0]">
</div>
<br />
<button type="submit">Submit</button>
</form>
Already have an account? Login here!
</div>
</div>
<script type="text/javascript">
$(function() {
var dataSourceField = $('#sign-up-organization-discovery-source');
var i = $('#sign-up-organization-discovery-source p').size();
var sourceCounter = 1;
$('#sign-up-add-discovery-source').on('click', function() {
$('<p><label for="discovery-source-field"><input type="text" id="discovery-source-field" size="20" name="discoverySource['+ sourceCounter++ +']" value="" placeholder="Discovery Source" /></label> Remove</p>').appendTo(dataSourceField);
i++;
return false;
});
$('#sign-up-organization-discovery-source').on('click', '.remove', function() {
if (i > 1) {
$(this).parent('p').remove();
i--;
}
return false;
});
});
</script>
</body>
To answer the last comment, I need to be able to make the code more readable, so I'm posting it here in a new answer.
Having thought about it a little more, it would make more sense to add it as custom 'getter' function. I'll also include the 'instanceMethods' to demonstrate how that works, as well.
var Organization = sequelize.define('organization', {
...
},{
freezeTableName: true,
classMethods: {
associate: function(db) {
Organization.belongsToMany(db.User, { through: 'member', foreignKey: 'user_id' });
},
},
// Here's where custom getters would go
getterMethods: {
discoverySources: function() {
return this.getDataValue('discoverySource');
}
},
// here's the instance methods
instanceMethods: {
getSourcesArray: function() {
return this.getDataValue('discoverySource');
}
}
});
Both of these options add the functions to each instance created by the Model. The main difference being in how they are accessed.
organization.discoverySources; // -> ['s1', 's2', etc...]
organization.getSourcesArray(); // -> ['s1', 's2', etc...]
note the additional () required on the instanceMethod. Those are added as functions of the instance, the getterMethods get added as properties.
setterMethods work the same way to allow you to define custom setters.
Hope that clarifies things a bit.

Meteor update user profile

I have no idea what's going wrong in my app. I'm trying to update a user profile. If a user has already a profile, it should display the current values of the profile. I have a SimpleSchema attached to the user collection.
<template name="updateCustomerProfile">
<div class="container">
<h1>Edit User</h1>
{{#if isReady 'updateCustomerProfile'}}
{{#autoForm collection="Users" doc=getUsers id="profileForm" type="update"}}
<fieldset>
{{> afQuickField name='username'}}
{{> afObjectField name='profile'}}
</fieldset>
<button type="submit" class="btn btn-primary">Update User</button>
<a class="btn btn-link" role="button" href="{{pathFor 'adminDocuments'}}">Back</a>
{{/autoForm}}
{{else}}
Nothing
{{/if}}
</div>
</template>
I have a template helper:
Template.updateCustomerProfile.events({
getUsers: function () {
//return Users.findOne();
return Meteor.user();
}
});
I have an Autoform hook
AutoForm.addHooks(['profileForm'], {
before: {
insert: function(error, result) {
if (error) {
console.log("Insert Error:", error);
AutoForm.debug();
} else {
console.log("Insert Result:", result);
AutoForm.debug();
}
},
update: function(error) {
if (error) {
console.log("Update Error:", error);
AutoForm.debug();
} else {
console.log("Updated!");
console.log('AutoForm.debug()');
}
}
}
});
Have the following route:
customerRoutes.route('/profile/edit', {
name: "updateCustomerProfile",
subscriptions: function (params, queryParams) {
this.register('updateCustomerProfile', Meteor.subscribe('usersAllforCustomer', Meteor.userId()));
},
action: function(params, queryParams) {
BlazeLayout.render('layout_frontend', {
top: 'menu',
main: 'updateCustomerProfile',
footer: 'footer'
});
}
});
and finally the following publication:
Meteor.publish('usersAllforCustomer', function (userId) {
check(userId, String);
var user = Users.findOne({_id: userId});
if (Roles.userIsInRole(this.userId, 'customer')) {
return Users.find({_id: userId});
}
});
And here is the collection:
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
},
organization : {
type: String,
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);
I'm sure the user object is passed in the publication. I can't update the profile: getting the following error (from Autoform debug):
Update Error: Object {$set: Object}
$set: Object
profile.firstName: "test_firstname"
profile.gender: "Female"
profile.lastName: "test_lastname"
profile.organization: "test_organisation
"username: "test_username"
How to go about updating a profile, staring blind....
You need to change your before AutoForm Hooks.
AutoForm.addHooks(['profileForm'], {
before: {
insert: function(doc) {
console.log('doc: ', doc);
return doc;
},
update: function(doc) {
console.log('doc: ', doc);
return doc;
},
},
});
While the after callback has the js standard (error, result) function signature, the before callback has just one parameter, the doc to insert/update. This is why you are always logging an 'error', it is just the doc you want to insert. Also you need to either return it, or pass it to this.result to actually insert/update the object in the db.
From the docs:
var hooksObject = {
before: {
// Replace `formType` with the form `type` attribute to which this hook applies
formType: function(doc) {
// Potentially alter the doc
doc.foo = 'bar';
// Then return it or pass it to this.result()
return doc; (synchronous)
//return false; (synchronous, cancel)
//this.result(doc); (asynchronous)
//this.result(false); (asynchronous, cancel)
}
},
There are a couple small issues so I'm not sure how to tackle your problem, but here's some things to address.
Publish Method
Local variable user is never used. Were you trying to use
it?
No need to include userId as a function parameter since you have
access to this.userId
The current user's profile is published by default so you don't need to use publish/subscribe unless you want to include/exclude fields, but then I would define a Meteor.publish(null, ...) so that it overrides the default current user publication
Note: If you remove publish usersAllforCustomer function, don't forget to remove it from route updateCustomerProfile
Use Global Helper currentUser
Here's how to update your template to use currentUser instead of getUsers
<template name="updateCustomerProfile">
<div class="container">
<h1>Edit User</h1>
{{#with currentUser}}
{{#autoForm collection="Users" doc=this id="profileForm" type="update"}}
<fieldset>
{{> afQuickField name='username'}}
{{> afObjectField name='profile'}}
</fieldset>
<button type="submit" class="btn btn-primary">Update User</button>
<a class="btn btn-link" role="button" href="{{pathFor 'adminDocuments'}}">Back</a>
{{/autoForm}}
{{else}}
Nothing
{{/with}}
</div>
</template>
Hope this helps.
The meteorpad indeed solved the issue. There was a mistake in the helper. In fact, the original code was:
Template.updateCustomerProfile.events({
getUsers: function () {
return Meteor.user();
}
});
So in above snippet I was using an 'events' instead of an 'helper'. Below is the correct code:
Template.updateCustomerProfile.helpers({
getUsers: function(){
return Meteor.user();
}
});

Validation error in Keystone JS

I am trying to build a contact form which is very similar to the one used in the keystone demo but i have hit a road block, While trying to save to db, I get the following errors
{ message: 'Validation failed',
name: 'ValidationError',
errors:
{ name:
{ name: 'ValidatorError',
path: 'name',
message: 'Name is required',
type: 'required' } } }
I have checked the fields on the form and also the request in the backend by doing a console.log but for some reason i still keep on getting the same error.
Here is what I have in my jade file
section#contact-container
section#contact.contact-us
.container
.section-header
// SECTION TITLE
h2.white-text Get in touch
// SHORT DESCRIPTION ABOUT THE SECTION
h6.white-text
| Have any question? Drop us a message. We will get back to you in 24 hours.
if enquirySubmitted
.row
h3.white-text.wow.fadeInLeft.animated(data-wow-offset='30', data-wow-duration='1.5s', data-wow-delay='0.15s') Thanks for getting in touch.
else
.row
form#contact.contact-form(method="post")
input(type='hidden', name='action', value='contact')
.wow.fadeInLeft.animated(data-wow-offset='30', data-wow-duration='1.5s', data-wow-delay='0.15s')
.col-lg-4.col-sm-4(class=validationErrors.name ? 'has-error' : null)
input.form-control.input-box(type='text', name='name', value=formData.name, placeholder='Your Name')
.col-lg-4.col-sm-4
input.form-control.input-box(type='email', name='email', value=formData.email, placeholder='Your Email')
.col-lg-4.col-sm-4
div(class=validationErrors.enquiryType ? 'has-error' : null)
input.form-control.input-box(type='text', name='enquiryType', placeholder='Subject', value=formData.enquiryType)
.col-md-12(class=validationErrors.message ? 'has-error' : null)
.col-md-12.wow.fadeInRight.animated(data-wow-offset='30', data-wow-duration='1.5s', data-wow-delay='0.15s')
textarea.form-control.textarea-box(name='message', placeholder='Your Message')= formData.message
button.btn.btn-primary.custom-button.red-btn.wow.fadeInLeft.animated(data-wow-offset='30', data-wow-duration='1.5s', data-wow-delay='0.15s', type='submit') Send Message
and this is how my schema and route file looks like
var keystone = require('keystone'),
Types = keystone.Field.Types;
var Enquiry = new keystone.List('Enquiry', {
nocreate: true,
noedit: true
});
Enquiry.add({
name: { type: Types.Name, required: true },
email: { type: Types.Email, required: true },
enquiryType: { type: String },
message: { type: Types.Markdown, required: true },
createdAt: { type: Date, default: Date.now }
});
Enquiry.schema.pre('save', function(next) {
this.wasNew = this.isNew;
next();
});
Enquiry.schema.post('save', function() {
if (this.wasNew) {
this.sendNotificationEmail();
}
});
Enquiry.schema.methods.sendNotificationEmail = function(callback) {
var enqiury = this;
keystone.list('User').model.find().where('isAdmin', true).exec(function(err, admins) {
if (err) return callback(err);
new keystone.Email('enquiry-notification').send({
to: admins,
from: {
name: 'Wheatcroft Accounting',
email: 'contact#abc.com'
},
subject: 'New Enquiry for **',
enquiry: enqiury
}, callback);
});
};
Enquiry.defaultSort = '-createdAt';
Enquiry.defaultColumns = 'name, email, enquiryType, createdAt';
Enquiry.register();
This is the route file
var keystone = require('keystone'),
async = require('async'),
Enquiry = keystone.list('Enquiry');
exports = module.exports = function(req, res) {
var view = new keystone.View(req, res),
locals = res.locals;
locals.section = 'contact';
locals.formData = req.body || {};
locals.validationErrors = {};
locals.enquirySubmitted = false;
view.on('post', { action: 'contact' }, function(next) {
var newEnquiry = new Enquiry.model();
var updater = newEnquiry.getUpdateHandler(req);
updater.process(req.body, {
flashErrors: true,
fields: 'name, email, enquiryType, message',
errorMessage: 'There was a problem submitting your enquiry:'
}, function(err) {
if (err) {
locals.validationErrors = err.errors;
console.log(err);
} else {
locals.enquirySubmitted = true;
}
next();
});
});
view.render('contact');
}
I believe the problem has to do with the way KeystoneJS handles Types.Name field types internally.
In your jade file, you should reference your name field using a path to its virtual name.full property. Internally name.full has a setter that splits the name into name.first and name.last. So, if you wish to have separate input for the first and last name you should use name.first and name.last. If you want a single input to enter the full name you should use name.full.
Try replacing the input control for your name field:
input.form-control.input-box(type='text', name='name', value=formData.name, placeholder='Your Name')
with this:
input.form-control.input-box(type='text', name='name.full', value=formData['name.full'])

Finding cause of template being destroyed/recreated

trying to debug something. On our client, we have a Accounts.createUser() call, which include a callback that looks like:
function(err) {
if (err) {
Session.set('entryError', err.reason);
}
else {
return Router.go('/');
}
}
With this setup, a normal signup (i.e. with no errors) works fine. However, if there's an error, the template is destroyed, created, and rendered, twice. I found this question, and went on a hunt for potential reactive variables triggering this. The only thing I can find that changes between the two template destroyed/created/rendered calls is Meteor.loggingIn() (including session variables). That doesn't seem to be causing this, because when I removed all references to it and dependencies on it, the problem continued.
Any pointers?
ETA: per the request below.
signUpPage.html:
<template name='signUpPage'>
<main id="signUpPage">
<h1 class="accountsTitle">Sign Up</h1>
<p id="signInPrompt">If you already have an account sign in.</p>
<form id='signUpForm'>
{{> entryError}}
<div class="form-group">
<label for="usernameInput">Username</label>
<input id="usernameInput" type="string" class="form-control" value=''>
</div>
<div class="form-group">
<label for="emailInput">Email Address</label>
<input id="emailInput" type="email" class="form-control" value=''>
</div>
<div class="form-group">
<label for="passwordInput">Password</label>
<input id="passwordInput" type="password" class="form-control" value=''>
</div>
<div class="form-group">
<label for="confirmPasswordInput">Confirm Password</label>
<input id="confirmPasswordInput" type="password" class="form-control" value=''>
</div>
<div class="form-group">
<label for="signupCodeInput">Signup Code</label>
<input id="signupCodeInput" class="form-control" value=''>
</div>
<button type="submit" class="btn btn-primary btn-block">Sign up</button>
</form>
</main>
</template>
signUpPage.js
Template.signUpPage.events({
'submit #signUpForm': function(event, template) {
event.preventDefault();
// Get the input values from the form
var username = template.find("#usernameInput").value.trim();
var email = template.find("#emailInput").value.trim();
var signupCode = template.find("#signupCodeInput").value;
var password = template.find("#passwordInput").value;
var confirmPassword = template.find("#confirmPasswordInput").value;
// Log the signup attempt
var signupAttempt = {'type':'signup', 'username':username, 'email':email, 'password':password, 'signupCode':signupCode};
Logins.insert(signupAttempt);
// Validate username presence
if (!username.length)
return Session.set('entryError', 'Username is required');
// Validate email presence
if (!email.length)
return Session.set('entryError', 'Email address is required');
// Validate password
var passwordErrors = validatePassword(password, confirmPassword);
if (passwordErrors.length) {
var errorsString = passwordErrors.join("\r\n");
Session.set('entryError', errorsString);
return;
}
// Validate signup code
if (!signupCode.length)
return Session.set('entryError', 'Signup code is required');
Meteor.call('createAccount', username, email, password, signupCode, function(err, data) {
if (err) {
Session.set('entryError', err.reason);
return;
}
else {
Meteor.loginWithPassword(username, password);
return Router.go('/');
}
});
}
});
Template.signUpPage.destroyed = function () {
Session.set("entryError", null);
};
Template.signUpPage.created = function() {
document.title = "Grove OS | Sign Up";
};
The following are js files where entryError is used:
Template.signInPage.events({
'click #signInButton': function(evt, template) {
evt.preventDefault();
// Making lowercase here, check on the server should be case insensitive though
var email = template.find('#emailInput').value.trim().toLowerCase();
var password = template.find('#passwordInput').value;
if (!email.length)
return Session.set('entryError', 'Email is blank');
if (!password.length)
return Session.set('entryError', 'Password is blank');
var loginAttempt = {'type':'login', 'email':email, 'date':new Date()};
return Meteor.loginWithPassword(email, password, function(error) {
if (error) {
loginAttempt.status = 'error';
Logins.insert(loginAttempt);
return Session.set('entryError', error.reason);
} else{
loginAttempt.status = 'success';
Logins.insert(loginAttempt);
return Router.go("/");
}
});
},
'click #signUpButton': function(evt, template) {
evt.preventDefault();
Router.go("signUpRoute");
},
'click #forgotPasswordButton': function(evt, template) {
evt.preventDefault();
Router.go("forgotPasswordRoute");
}
});
Template.signInPage.destroyed = function () {
Session.set("entryError", null);
};
Template.signInPage.created = function() {
document.title = "Grove OS | Sign In";
};
-
Template.resetPasswordPage.helpers({
error: function() {
return Session.get('entryError');
}
});
Template.resetPasswordPage.events({
'submit #resetPasswordForm': function(event, template) {
event.preventDefault();
var password = template.find('#passwordInput').value;
var confirmPassword = template.find('#confirmPasswordInput').value;
// Validate password
var passwordErrors = validatePassword(password, confirmPassword);
if (passwordErrors.length) {
var errorsString = passwordErrors.join("\r\n");
return Session.set('entryError', errorsString);
} else {
return Accounts.resetPassword(Session.get('resetToken'), password, function(error) {
if (error) {
return Session.set('entryError', error.reason || "Unknown error");
} else {
Session.set('resetToken', null);
return Router.go("/");
}
});
}
}
});
Template.resetPasswordPage.created = function () {
document.title = "Grove OS | Reset Password";
};
-
Template.forgotPasswordPage.events({
'submit #forgotPasswordForm': function(event, template) {
event.preventDefault();
var email = template.find("#forgottenEmail").value;
if (!email.length) {
return Session.set('entryError', 'Email is required');
} else {
return Accounts.forgotPassword({
email: email
}, function(error) {
if (error)
return Session.set('entryError', error.reason);
else
return Router.go("/");
});
}
}
});
Template.forgotPasswordPage.created = function () {
document.title = "Grove OS | Forgot Password";
};
-
Router code (combined from 2 files):
//--------------------------------------------------------------
// Global Configuration
Router.configure({
layoutTemplate: 'appBody',
notFoundTemplate: 'notFoundPage',
loadingTemplate: 'loadingPage',
yieldTemplates: {
'appHeader': {to: 'header'},
'appFooter': {to: 'footer'}
}
});
// Have to sign in to access all application pages
Router.onBeforeAction(function() {
console.log("Global router onBeforeAction calle");
// if (!Meteor.loggingIn() && !Meteor.user()) {
if(!Meteor.user()){
this.redirect('/sign-in');
}
this.next();
}, {
// whitelist which routes you don't need to be signed in for
except: [
'signUpRoute',
'signInRoute',
'forgotPasswordRoute',
'signOutRoute',
'resetPasswordRoute',
'pageNotFoundRoute'
]
});
// Subscriptions application-wide
Router.waitOn(function() {
if (Meteor.loggingIn() || Meteor.user())
return Meteor.subscribe("userGroups");
});
//--------------------------------------------------------------
// Root route
Router.route('landingRoute', {
path: '/',
onBeforeAction: function(){
console.log("other global one is being called");
// if (!Meteor.loggingIn() && !Meteor.user()){
if(!Meteor.user()){
this.redirect('/sign-in');
}else{
this.redirect('/grove/dashboard');
}
this.next();
}
});
//--------------------------------------------------------------
// Static Routes
Router.route('/glossary', {
path: '/glossary',
template: 'glossaryPage'
});
Router.route('/eula', {
path: '/eula',
template: 'eulaPage'
});
Router.route('/privacy', {
path: '/privacy',
template: 'privacyPage'
});
Router.route('/about', {
path: '/about',
template: 'aboutPage'
});
Router.route("signUpRoute", {
path: "/sign-up",
template: "signUpPage"
});
Router.route("signInRoute", {
path: "/sign-in",
template: "signInPage"
});
Router.route('signOutRoute', {
path: '/sign-out',
template: "signOutPage",
onBeforeAction: function() {
Meteor.logout();
Router.go('/');
this.next();
}
});
Router.route("forgotPasswordRoute", {
path: "/forgot-password",
template: "forgotPasswordPage",
});
Router.route('resetPasswordRoute', {
path: 'reset-password/:resetToken',
template: "resetPasswordPage",
data: function() {
Session.set('resetToken', this.params.resetToken);
return ;
}
});
Router.route("404Route", {
path: "/page-not-found",
template: "notFoundPage",
});
Router.route("dashboardRoute", {
path: "/dashboard",
template: "dashboardPage"
});
Router.route('createShrub', {
path: '/tools/createShrub',
template: 'upsertShrubPage',
waitOn: function(){
},
data: function () {
},
});
// TODO figure out how to dynamically render templates
// based on if the slug is a group, user, or nothing
// and also conditionally subscribe
Router.route('profileRoute', {
path: '/:ownerSlug',
template: 'myProfilePage'
});
Router.route('groveRoute', {
path: '/:ownerSlug/:groveSlug',
template: 'grovePage',
data: function () {
return Groves.findOne({ slug: this.params.groveSlug });
},
});
Router.route('shrubRoute', {
path: '/:ownerSlug/:groveSlug/:shrubSlug',
template: 'shrubStaticPage',
data: function() {
Session.set("currentShrub", this.params.shrubSlug);
return ShrubTemplates.findOne({ slug: this.params.shrubSlug });
},
action: function() {
if (this.ready())
this.render();
else
this.render('loadingHolder');
}
});
Well, it turned out that as part of the router there was this function:
Router.waitOn(function() {
if (Meteor.loggingIn() || Meteor.user())
return Meteor.subscribe("userGroups");
});
The change in Meteor.loggingIn() caused this function to run, which we saw with our loading page getting displayed briefly. We're changed the if statement so that it no longer contains the Meteor.loggingIn() check. A little embarrassing, really--I swear I looked at that line before. Not sure what happened in my thought process to miss this. At least now I have a better understanding of Iron Router.

Categories