Meteor: How should I write this Iron Router route? - meteor

I'm trying to rewrite my Iron Router adminhome router but when I click on the link to /admin/home I get the error below.
How should I rewrite this route?
Router.route('adminhome', {
layoutTemplate: 'adminlayout',
path:'/admin/home',
template: 'adminarea',
onBeforeAction: function() {
if (Meteor.loggingIn()) {
this.render(this.loadingTemplate);
} else if(!Roles.userIsInRole(Meteor.user(), ['admin'])) {
console.log('redirecting');
this.redirect('/');
} else {
this.next();
}
}
});
This is the error I get:
Exception from Tracker recompute function:
debug.js:41 Error: Expected template rendered with Blaze.render
at Object.Blaze.remove (view.js:679)
at DynamicTemplate.destroy (iron_dynamic-template.js:327)
at null._render (iron_layout.js:400)
at doRender (view.js:351)
at view.js:199
at Function.Template._withTemplateInstanceFunc (template.js:457)
at view.js:197
at Object.Blaze._withCurrentView (view.js:538)
at viewAutorun (view.js:196)
at Tracker.Computation._compute (tracker.js:323)
Here's my updated code. The problem might be related to the {{>yield}} line. That's just a guess though.
Router.route('adminhome', {
layoutTemplate: 'adminlayout',
path:'/admin/home',
template: 'adminarea',
onBeforeAction: function() {
if (Meteor.loggingIn()) {
//this.render(this.loadingTemplate);
this.render("loadingPage");
} else if(!Roles.userIsInRole(Meteor.user(), ['admin'])) {
console.log('redirecting');
this.redirect('/');
} else {
this.next();
}
}
});
<template name="adminTemplate">
{{#if isInRole "admin"}}
{{> adminarea}}
{{else}}
Must be admin to see this...
{{/if}}
</template>
<template name="adminarea">
{{>yield}}
</template>

In the line of your code...
this.render(this.loadingTemplate);
...replace this.loadingTemplate with the actual loading template name.
Eg.
this.render("LoadingTemplateName");

Related

Password Reset token is returning null, although defined

I'm utilizing useraccounts:unstyled, accounts-base, accounts-password and trying to implement a password resetting feature.
I have my route defined as such:
FlowRouter.route('/reset-password/:token', {
name: 'reset-password',
onBeforeAction: function()
Accounts._resetPasswordToken = this.params.token;
this.next();
},
action(params){
Accounts._resetPasswordToken = params.token;
mount(MainLayout, {
content: (<ForgotPassword />)
});
}
});
My template defined as such:
<template name="ForgotPasswordModal">
{{#if $not currentUser}}
<div class="forgot-modal {{$.Session.get 'nav-toggle'}}" id="{{checkState}}">
<i class="fa fa-close resetPwd"></i>
{{> atForm}}
</div>
{{/if}}
</template>
And my helper functions defined as:
if (Meteor.isClient) {
Template.ForgotPasswordModal.onCreated(function(){
if(Accounts._resetPasswordToken){
Session.set('resetPasswordToken', Accounts._resetPasswordToken);
}else{
console.log("else");
}
});
Template.ForgotPasswordModal.helpers({
checkState() {
return (AccountsTemplates.getState() == 'resetPwd') ? 'forgot-modal' : '';
}
});
Template.ForgotPasswordModal.events({
"submit .at-btn": (event)=>{
event.preventDefault();
console.log(event);
password = document.getElementById('reset-password-new-password').value;
console.log("password", password);
if(password){
Accounts.resetPassword(Session.get('resetPasswordToken'), password, (error)=>{
if(error){
console.log("error: ", error);
}else{
console.log("success");
Session.set('resetPasswordToken', null);
}
});
}
}
});
}
Upon clicking submit I get Error: Match error: Expected string, got null (unknown).
Although if I load the route up (with a valid token) and run Session.get('resetPasswordToken') the token is returned validly.
I was getting this for a few days, couldn't figure it out... then after some rearrangement it finally worked.
And you don't have to use Meteor's default route & form for resetting the password.
You're close #Sleep Deprived Bulbasaur, your route should look like this:
FlowRouter.route('/reset-password/:token', {
name: 'reset-password',
action(params){
Session.set('_resetPasswordToken', params.token);
mount(MainLayout, {
content: (<ForgotPassword />)
});
}
});
I did not need the onBeforeAction, Accounts._resetPasswordToken, or this.next(), and it works just fine and logs you in automatically.
Your template should have something like this:
if (!validateForm(password,passwordAgain)) {
console.log('Your passwords dont match');
} else if (!isValidPassword(password, passwordAgain)) {
console.log('You do not have valid passwords');
} else {
let token = Session.get('_resetPasswordToken');
Accounts.resetPassword(token, password, function(err) {
check(token, String);
if (err) {
console.log('We are sorry but something went wrong.');
} else {
console.log('Your password has been changed. Welcome back!');
}
});
}
Please try using this way:
FlowRouter.route('/#/reset-password/:token');
This is default route for reset Password.

Iron router Couldn’t find a template named... Are you sure you defined it?

I am trying to render a template on a given page but I get the following error:
Couldn't find a template named "adPage" or "adPage". Are you sure you defined it?
myapp/lib/router.js
This is how I defined the route:
Router.route("/dashboard/adpage/:_id", {
// name:"adPage",
template:"adPage",
data:function(){
return Ads.findOne({_id: this.params._id});
},
onBeforeAction : function()
{
if(Meteor.userId())
{
//user is loggedin continue the route
this.next();
}
else {
console.log("user not loggin, redirect to login page");
this.render('login');
}
},
onAfterAction: function(){
document.title = 'Annonce';
},
waitOn:function(){
return Meteor.subscribe("adDetails",this.params._id);
}
});
myapp/client/main.html
<template name="main">
...
{{> yield}}
...
</template>
myapp/client/adPage/adPage.html
<template name="adPage">
{{title}}
...
</template>
myapp/client/adPage/adPage.js
Template.adPage.onCreated(function() {
console.log("on created");
});
If I move the adPage template to my main.html file, I no longer have the error (I can see the title) but the onCreated is not called.
I tried to put everything in the same client folder and renaming adPage.js to _adPage.js and everything worked as expected.
So I suspect something wrong with the load order but can't figure out what...
Thanks !
If you are using an adblocker. Try to disable it. Its probably because of the filename

if user login show **logintemplate ` in meteor otherwise show `index template`?

if user login show logintemplate in meteor otherwise show index template.I want when user login show the after login page it is ok .But i am asking when we are give at web url afterlogin template like(/admin) it will open i want when ever we give /admin show the home page not showing admin page.plz suggest me.
Maybe you are looking this.
With JSCode.
Router.route('/', function () {
if(Meteor.userId(){
this.render('loginTemplate');
}else{
this.render('login')
}
});
Using Spacebars.
{{#if currentUser}}
{{> loginTemplate}}
{{else}}
{{> login}}
{{/if}}
Using onBeforeAction
First The function
var requireLogin = function() {
if (! Meteor.user()) {
if (Meteor.loggingIn()) {
this.render(this.loadingTemplate);
} else {
this.render('accessDenied');
}
} else {
this.next();
}
}
Second onBeforeAction
Router.onBeforeAction(requireLogin, {only: 'loginTemplate'}); // this will only been applied to the `loginTemplate`.

Meteor Iron Router load template based on dynamic name

I would like to load a meteor template using iron-router but the template that I'm loading needs to be dynamic, I have tried a couple different approaches but none are working.
My router
Router.route('/forms/add-form/:template', {
name: 'addForm',
layoutTemplate: 'layoutApp',
waitOn: function() {
return Meteor.subscribe('producersList');
},
data: function() {
return Producers.find();
}
});
The router go
Router.go('addForm', {template: this.template});
The url is fine now I first tried having this in my router
name: this.params.template,
But that doesn't work I'm now trying the following in my addForm template
{{> UI.dynamic template=formToLoad data=myDataContext}}
formToLoad:function(){
console.log('aaaa ' + this.template);
}
});
You can pass data into template in route:
Router.route('/forms/add-form/:template', {
name: 'addForm',
layoutTemplate: 'layoutApp',
waitOn: function() {
return Meteor.subscribe('producersList');
},
data: function() {
return {
producers: Producers.find(),
formToLoad: this.params.template //here pass the template name
}
}
});
and in your template:
<template name="addForm">
{{> Template.dynamic template=formToLoad}}
</template>
Now if we run:
Router.go('addForm', {template: 'someTemplateName'});
It should load template with name 'someTemplateName'. Use camelCase syntax for template names because you will get syntax error with 'some-template-name' when you will define helpers or events for template.

Default error page

I would like to define a default error page in meteor. That is if application is crashing or other error occurs the user should be redirected to a "friendly" page that says something like : system is unavailable , please contact etc etc.
Is there any way to accomplish this or something similar ?
Thank you
You have to use BackboneJS(Backbone Router) for routing. With this code the session variable 'page_type' let's you know if you are on a wrong url.
var BackboneRouter = Backbone.Router.extend({
routes: {
"/": "default",
":error": "list"
},
default: function () {
Session.set("page_type", "default");
},
error: function () {
Session.set("page_type", "error");
}
});
Router = new BackboneRouter;
Meteor.startup(function () {
Backbone.history.start({pushState: true});
});
Now you can use the 'page_type' to tell the template engine which template to load.
Template.tmp.route = function () {
if (Session.get("page_type") == "default") {
return true;
} else {
return false;
}
<template name="tmp">
{{#if route}}
{{> default}}
{{else}}
{{> error}}
{{/if}}
</template>

Resources