Goal: Be able to link directly to profile pages or refresh pages.
Problem: If you visit this profile page (https://pimp_stack.meteor.com/pevprofile/PqZrKZYTfy7EHfQei) you see the page for a few seconds, then you're rerouted to the home page.
How to make stay on the profile page?
The routing code:
Router.route('/', function () {
// render the Home template with a custom data context
this.render('Home');
});
// Login / Logout
Router.route('/login');
Router.route('/logout', function () {
Meteor.logout();
this.render('Home');
});
// given a url like "/pevprofile/<id>
Router.route('/pevprofile/:_id', function () {
this.render('/pevprofile');
});
The template code:
<template name="pevprofile">
<div class="container-fluid">
<h2>Profile</h2>
{{> PevDetails}}
</div>
</template>
<template name="PevDetails">
PEV Details
</template>
You might want to re-check this. Its working fine on my end. I'm seeing the profile page no redirection after several seconds.
Related
I'm using the Polymer Starter Kit and polymerfire to create a firebase app with two routes: 'staff' and 'donate'. The donate route is public and the staff route is private. I'd like to protect the staff route such that only logged in users who have an email ending with mycompany.com can access it. Unauthenticated users will be redirected to /donate.
My first attempt was to wrap links to and declarations of those routes in dom-if templates. This works to prevent users from seeing the route, but if a user is logged in, they will not be able to navigate to that route from the address bar - they'll have to click on a link to the route in the app first. This is confusing: the address bar may still say 'staff' even though the 'donate' page is shown.
<iron-selector selected="[[page]]" attr-for-selected="name" class="drawer-list" role="navigation">
<template is="dom-if" if="[[user]]" restamp="true">
<a name="staff" href="/staff">Staff</a>
</template>
<a name="donate" href="/donate">Donate</a>
</iron-selector>
<iron-pages
selected="[[page]]"
attr-for-selected="name"
fallback-selection="donate"
role="main">
<template is="dom-if" if="[[user]]" restamp="true">
<ksybf-staff name="staff"></ksybf-staff>
</template>
<ksybf-donate name="donate" route="[[subroute]]"></ksybf-donate>
</iron-pages>
I've also tried imperatively preventing route loading:
_routePageChanged: function(page) {
if (this.user) {
this.page = page || 'donate';
} else {
this.page = 'donate';
}
},
This produces similar results: initial browsing to /staff loads the 'donate' route, even though the address bar shows //app/staff.
How can I protect routes in a way which just works from the user's perspective?
Add an id to your <iron-pages>.
Add a iron-select listener to it.
Inside the listener function, add the logic to redirect in case the user is not logged in.
It would look like this:
For the <iron-pages>:
<iron-pages
id="selector"
selected="[[page]]"
attr-for-selected="name"
fallback-selection="donate"
role="main">
<ksybf-staff name="staff"></ksybf-staff>
<ksybf-donate name="donate" route="[[subroute]]"></ksybf-donate>
</iron-pages>
Add the listener:
listeners: {
'selector.iron-select': 'pageChanged'
}
And the function:
pageChanged: function(e){
var page = this.$.selector.selected;
switch (page){
case 'staff':
if (userIsNotLoggedIn){
//Ideally, I would send a toast here saying that the user should be logged in
window.location.href = '/donate'
}
}
}
How I approach this is to utilise the "selected-attribute" of iron-pages.
<iron-pages selected-attribute="active">
This will set the active attribute in your staff and donate pages.
Use an observer on the active attribute in your staff component and if active === true then do your check. If they aren't authenticated/authorized then just kick them back to where they belong.
I´m developing a map app in meteor with leaflet. To show data in a marker popup I created a route and call it from and iframe on the popup. When I display the route alone, it's reactive. When the same route is displayed in the popup, it's not.
I have set up a route with Iron Route. When I navigate to the page everything is OK.
If I put the route in an iframe in another meteor page it renders but is not reactive..
Code below:
Template
<template name="prueba">
{{#each Clientes}}
{{Nombre}}
{{/each}}
</template>
Route
Router.route('/prueba', function () {
this.render('prueba');
});
Helper
Template.prueba.helpers ({
Clientes: function() {
return clientes.find({ lunes: Session.get("Lunes") });
}
});
Popup
map.on('locationfound', function(e){
position= new L.marker(e.latlng,{icon:gpsIcon});
position.addTo(map);
map.setZoom(18);
position.bindPopup('<iframe src="/prueba" style="border:none"> </iframe>').openPopup();
});
I have a main page which lists a few text items ("Ideas"), which are clickable links. Clicking on them should take you to a page where you can edit them. Here's my html:
<head>
<title>Ideas</title>
</head>
<body>
</body>
<template name="Ideas">
<ul>
{{#each ideas}}
{{> idea}}
{{/each}}
</ul>
</template>
<template name="idea">
<li>{{text}}</li>
</template>
<template name="ShowIdea">'
<div class="editable" contentEditable="true">{{text}}</div>
</template>
I've added Iron:Router to my project to allow for moving between the pages. Here's the javascript:
Ideas = new Mongo.Collection("ideas");
if (Meteor.isClient) {
Router.route('/', function() {
this.render('Ideas');
});
Router.route('/idea/:_id', function() {
var idea = Ideas.findOne({_id: this.params._id});
this.render('ShowIdea', {text: idea.text});
});
Template.Ideas.helpers({
ideas: function () {
return Ideas.find({});
}
});
}
I inserted a single idea to my Mongo DB using the Meteor Mongo command line tool. That single item shows up properly on my main page. Here's what the HTML looks like in my debugger for the main page:
<html>
<head>...</head>
<body>
<ul>
<li>
The first idea ever
</li>
</ul>
</body>
</html>
Clicking on that link takes me to a new page with an address of:
http://localhost:3000/idea/ObjectID(%22550b7da0a68cb03381840feb%22)
But nothing shows up on the page. In the debugger console I see this error message + stack trace, but it means nothing to me since it all seems to be pertaining to iron-router and meteor, not code which I actually wrote:
Exception in callback of async function: http://localhost:3000/Idea.js?2fd83048a1b04d74305beae2ff40f2ea7741d40d:10:44
boundNext#http://localhost:3000/packages/iron_middleware-stack.js?0e0f6983a838a6516556b08e62894f89720e2c44:424:35
http://localhost:3000/packages/meteor.js?e53378596562e8922a6369c955bab1e047fa866b:978:27
onRerun#http://localhost:3000/packages/iron_router.js?a427868585af16bb88b7c9996b2449aebb8dbf51:520:13
boundNext#http://localhost:3000/packages/iron_middleware-stack.js?0e0f6983a838a6516556b08e62894f89720e2c44:424:35
http://localhost:3000/packages/meteor.js?e53378596562e8922a6369c955bab1e047fa866b:978:27
onRun#http://localhost:3000/packages/iron_router.js?a427868585af16bb88b7c9996b2449aebb8dbf51:505:15
boundNext#http://localhost:3000/packages/iron_middleware-stack.js?0e0f6983a838a6516556b08e62894f89720e2c44:424:35
http://localhost:3000/packages/meteor.js?e53378596562e8922a6369c955bab1e047fa866b:978:27
dispatch#http://localhost:3000/packages/iron_middleware-stack.js?0e0f6983a838a6516556b08e62894f89720e2c44:448:7
_runRoute#http://localhost:3000/packages/iron_router.js?a427868585af16bb88b7c9996b2449aebb8dbf51:543:17
dispatch#http://localhost:3000/packages/iron_router.js?a427868585af16bb88b7c9996b2449aebb8dbf51:844:27
route#http://localhost:3000/packages/iron_router.js?a427868585af16bb88b7c9996b2449aebb8dbf51:710:19
boundNext#http://localhost:3000/packages/iron_middleware-stack.js?0e0f6983a838a6516556b08e62894f89720e2c44:424:35
http://localhost:3000/packages/meteor.js?e53378596562e8922a6369c955bab1e047fa866b:978:27
boundNext#http://localhost:3000/packages/iron_middleware-stack.js?0e0f6983a838a6516556b08e62894f89720e2c44:371:18
http://localhost:3000/packages/meteor.js?e53378596562e8922a6369c955bab1e047fa866b:978:27
dispatch#http://localhost:3000/packages/iron_middleware-stack.js?0e0f6983a838a6516556b08e62894f89720e2c44:448:7
http://localhost:3000/packages/iron_router.js?a427868585af16bb88b7c9996b2449aebb8dbf51:390:21
_compute#http://localhost:3000/packages/tracker.js?21f0f4306879f57e10ad3a97efe9ea521c5b5775:308:36
Computation#http://localhost:3000/packages/tracker.js?21f0f4306879f57e10ad3a97efe9ea521c5b5775:224:18
autorun#http://localhost:3000/packages/tracker.js?21f0f4306879f57e10ad3a97efe9ea521c5b5775:499:34
http://localhost:3000/packages/iron_router.js?a427868585af16bb88b7c9996b2449aebb8dbf51:388:17
nonreactive#http://localhost:3000/packages/tracker.js?21f0f4306879f57e10ad3a97efe9ea521c5b5775:525:13
dispatch#http://localhost:3000/packages/iron_router.js?a427868585af16bb88b7c9996b2449aebb8dbf51:387:19
dispatch#http://localhost:3000/packages/iron_router.js?a427868585af16bb88b7c9996b2449aebb8dbf51:1688:22
onLocationChange#http://localhost:3000/packages/iron_router.js?a427868585af16bb88b7c9996b2449aebb8dbf51:1772:33
_compute#http://localhost:3000/packages/tracker.js?21f0f4306879f57e10ad3a97efe9ea521c5b5775:308:36
_recompute#http://localhost:3000/packages/tracker.js?21f0f4306879f57e10ad3a97efe9ea521c5b5775:322:22
flush#http://localhost:3000/packages/tracker.js?21f0f4306879f57e10ad3a97efe9ea521c5b5775:452:24
And then it ends with this warning message:
Route dispatch never rendered. Did you forget to call this.next() in an onBeforeAction?
I don't have an onBeforeAction (I'm not even sure what that is)... so I don't think that message pertains to me?
I just started using Meteor the other day and just added iron-router not 24 hours ago, so I'm a bit lost here. Any pointers on how I can debug and fix this would be great.
Two things need fixing:
When you insert documents from the shell they are assigned _id values which are mongo ObjectIDs, whereas meteor defaults to using strings. This explains the weird URL. To avoid this problem, it's generally best to initialize your data from the server. Here's an example:
if (Meteor.isServer) {
Meteor.startup(function() {
if (Ideas.find().count() === 0) {
Ideas.insert({text: 'feed the cat'});
}
});
}
Now after a $ meteor reset you will always start with one cat-related idea.
If you wish to pass a context to your template, you'll need to use the data attribute like so:
Router.route('/idea/:_id', function() {
this.render('ShowIdea', {
data: function () {return Ideas.findOne({_id: this.params._id})}
});
});
See this example from the docs. After making those changes, the code worked correctly for me.
How do you get a Meteor app to start up on a particular page? If you don't control this, then the browser remembers where you were in the app when you last closed the app, and it tries to load that old location. Which is fine, if that's what you want, but if not, then what do you do?
Using iron-router in my app, this used to work:
Meteor.startup(function () {
Router.go('/');
});
Now this throws an error in Router.js, complaining that self._location is undefined. It's as if the call to Router.go() is happening too soon now. Is there a way to know when Router is ready for a go() call? Or a way to introduce a delay here?
_________________EDIT_________________
In an attempt to solve this, I have reduced everything down to the essentials. Here's all my code, 2 files in total:
newPL.js:
Router.configure({
layoutTemplate: 'layout'
});
Router.map(function () {
this.route('home', {
path: '/',
});
this.route('main', {
path: '/main',
});
});
if (Meteor.isClient) {
Meteor.startup(function () {
Router.go('home');
});
}
and newPL.html:
<head>
<title>newPL</title>
</head>
<template name='layout'>
<div>
{{> yield}}
</div>
</template>
<template name='home'>
<div>
Welcome to Planet Lingo!
<a href='/main'>GO</a>
</div>
</template>
<template name='main'>
<div>
<h1>Main</h1>
</div>
</template>
This looks like a bug in iron-router. Iron router does a Meteor.defer around router.start see: Iron-router source line 34
You can work around this by using Meteor.defer yourself
Meteor.startup(function () {
Meteor.defer(function () {Router.go('home');});
});
This works fine as your defer gets put below the one thats created by 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