Using Meteor, useraccounts-core ensureSignedIn plugin won't except '/' route - meteor

I am trying to use the ensureSignedIn plugin on all routes except for a front 'home' page that has buttons to login to separate parts of the site.
Here's my route for 'home':
Router.route('/', function () {
this.render('home');
});
Here's the line for the plugin and exceptions:
Router.plugin('ensureSignedIn', {
except: ['home', 'atSignIn', 'atSignUp', 'atForgotPassword']
});
Both snippets are from my lib/routes.js file, if that makes a difference.
I've tried adding different route names in the except: portion, and they get correctly excepted, but I can't for the life of me get the 'home' route to not show "Must be logged in".
I've googled and read through gitHub issues and haven't seen anyone else with this problem, so it's probably something I'm doing wrong and not a bug with useraccounts or iron-router.

Set the name of the / route to root, then add that route name to the ensureSignedIn settings:
Router.route('/', {
name: 'root',
template: 'home',
action: function() {
this.render();
}
});
Router.plugin('ensureSignedIn', {
except: ['root', 'atSignIn', 'atSignUp', 'atForgotPassword', 'atResetPwd']
});

Related

My router doesn't work as expected

this is the router code
Router.route('screens', {
path: '/screenshots/:_id',
template: 'screens',
onBeforeAction: function(){
Session.set( "currentRoute", "screens" );
Session.set("screenshots", this.params._id);
this.next();
}
});
this is the helper for screenshots template
Template.screens.helpers({
ss: function () {
var screenshots = Session.get("screenshots");
return Products.findOne({ _id: screenshots});
}
});
and am calling it here
<h4>Click to view the Screenshots
When i click to view the screenshots URL, the URL should be this /screenshots/:_id based on my router configuration, but what i see in the browser is /screenshots/ without the _id and the page shows 404 - NOT FOUND.
Is it possible to create nested routes?
because before i click on the link that executes the above route. i will be in this route
Router.route('itemDetails', {
path: '/item/:_id',
template: 'itemDetails',
onBeforeAction: function(){
Session.set( "currentRoute", "itemDetails" );
Session.set("itemId", this.params._id);
this.next();
}
});
and this route works fine i can see the item _id, is it possible to create another route inside it that has for example this path /item/:_id/screenshots?
I have the _id stored in Session.get("itemId"). Is it possible to call it in the path of the route somehow?
I tried '/item' + '/screenshots' + '/' + Session.get("itemId") but didn't work
or there is other way to solve it?
The problem is not with the code in the question, the 404 page is occurring due to it not being passed an id into the path, the browser says /screenshots/ and not /screenshots/randomId because it is only being passed that from the link.
As per additions to the question and chat with Behrouz: Because the value is stored in session we can use
Template.registerHelper('session',function(input){
return Session.get(input);
});
to register a global template helper called session which can be called with {{session session_var_name}} and create the link as below:
<h4>Click to view the Screenshots

Routing to home screen when not signed in

I want to redirect all users to a home page if they are not logged in. Currently I am doing this:
Router.onBeforeAction(function() {
this.render('loading');
if (! Meteor.userId()) {
this.render('Home');
} else {
this.next();
}
});
Which I saw online, but this seems to be prevent my 'loading' template from ever showing and instead shows the default
Loading...
in the top left of the screen. If I change this.render('Home'); to this.redirect('/') I see the correct loading template. However in the '/' route I call another this.render('Home') which I think then triggers the onBeforeAction again which in turn will redirect to '/' which means you are now in an infinite loop of loading.
So what is the correct way to fix my Router.onBeforeAction to achieve my desried goal of making sure users that are not logged in can only see the Home template no matter what URL they type in and do this without messing up my custom loading template elsewhere on the site?
You need to have two before hooks. One is for 'loading' and one is to check if the user is logged in.
The 'loading' one is linked up to your subscriptions and is usually a preinstalled hook with iron router.
Router.onBeforeAction(function() {
if (! Meteor.userId()) {
this.render('Home');
} else {
this.next();
}
}, {except: ['route_one', 'route_two']});
Router.onBeforeAction('loading');
Your route:
Router.route('/', {
name: 'home',
subscriptions: function() {
//Array of Meteor.subscribe to wait for and display the loading template
return [Meteor.subscribe("a_subscription")]
},
loadingTemplate: 'loading',
action: function() {
this.render("Home_logged_in");
}
});
So here, if Meteor.subscribe("a_subscription") is loading it will display the loading template. If the user is logged in it will display the Home_logged_in template and if not logged in (on any route) the Home template.
You can also set exceptions using the names 'route_one' and 'route_two' for your templates (which you can rename to anything else). I named your home template home. But if you added home to the except list the onBeforeAction would not apply to home.
I use this onBeforeAction hook which redirect to the home page if the user is not logged in:
var userAuthHook = function() {
if (Meteor.userId()) {
//continue to the requested url
this.next();
} else {
//redirect to home
this.redirect('/');
}
};
Router.onBeforeAction(userAuthHook, {
except: ['home']
});
Router.route('/', {
name: 'home'
});
Note that I exclude the home page from the hook in order to avoid redirect loops and that the / route is named "home" to be referred to in the hook exclusions.
This works for me and also allows to use loading templates.

iron:router Meteor how to change route (save state in history) without changing the url

I am developing a meteor applicaton . For routing I am using iron:router .
I am changing some templates by changing a session variable.
Is there any way that without changing the url the user gets an entry in the browser history, that with a browser back the session variable changes back?
My Problem is: Some beta testers tested the app and tried to close some overlays they opened with the browser back button.
I'm not sure I understand your question 100%. But it sounds like you want to set a session variable to a specific value based off of a specific route to control the state of an overlay?
If that's the case, your best bet would be to use an onBeforeAction hook.
Here's how you could do that with a Route Controller:
PostController = RouteController.extend({
waitOn: function () {},
data: function () {},
onBeforeAction () {
Session.set('someSession', 'someValue');
},
action: function () {
this.render();
}
});
If you don't want to use a Route Controller, you can also just add a hook function and specify a route for which the hook should run on.
Edit
Router.onBeforeAction(function () {
Session.set('showOverlay', false);
this.next();
});
You can also specify routes that you don't want this before hook on:
Router.onBeforeAction(function () {
Session.set('showOverlay', false);
this.next();
}, { except: ['admin'] });

Iron Router template not registered on redirect

I have this simple check if user is logged in and if not - redirect to register page
Router.map(function () {
this.route('home', {
path: '/',
onBeforeAction: function (pause) {
if (!Meteor.user()) {
this.render('register');
pause();
}
}
});
this.route('register', {path: '/register'});
});
And getting
Exception from Tracker recompute function: Error: Couldn't find a template named "register" or "register". Are you sure you defined it?
When I go directly to /register, it does work.
Any ideas why?
this.render takes template name as argument, not route name
this.render('templateName'): Render the template named 'templateName'
into the main yield {{> yield}}.
Source
Replace this.render("register") with Router.go('register')
It is also beneficial to check if user is in logging in state:
if (!(Meteor.loggingIn() || Meteor.user())) {
console.log("User is not logged in");
Router.go("register");
pause()
}
To create the templates I was using the em tool and when I did em g:route register it named the template Register - with a capital R.
Renaming it in the render: this.render('Register'); did the trick.

Redirecting page with Iron-Router

Currently I am using the accounts packages supplied by Meteor to allow people to sign up for the site I am working on. I want to allow users to have a bio page, whenever I am logged into a particular person a side bar navigation appears with a lot of links one of which says "Bio". I want bio to redirect me from the home page to MY bio page i.e:
localhost:3000/ -> localhost:3000/bio/uSerId23453423434
Currently write now I am using Iron-Router to do this:
...
<li>Bio</li>
...
And in my Router I have:
Router.map(function() {
...
this.route('bio',
{path: '/bio/:_id',
data: function () { return {_id: Meteor.userId()} }
});
...
But when I click on the link I am not redirected anywhere. Any ideas as to what I am doing wrong?
you don't need the parameter _id in your path since you are already using Meteor.userId(). Iron-router won't render if it can't find the _id parameter in the template. Removing it will fix your issue:
Router.map(function() {
...
this.route('bio',
{path: '/bio',
data: function () { return {_id: Meteor.userId()} }
});
...
If you want to keep the path with the _id you should render using {{#with}} to set the data context, for your {{pathFor 'bio'}}
You can view more information at:
https://github.com/EventedMind/iron-router/blob/master/DOCS.md#path-functions-and-helpers

Resources