This is my route:
this.route('showItem', {
path: '/item/:_id',
template: 'layout',
yieldTemplates: {
'content': {to: 'content'},
'item_details': {to: 'details'}
},
notFoundTemplate: 'notFound',
data: function () {
return null; //for test
}
})
And notFound template, it's simple:
<template name="notFound">
Not found!
</template>
And I can't understand, why always renders item_details and never notFound.
I think it was Iron-Router 0.7 they added a requirement where you had to switch on global hooks:
Router.onBeforeAction("dataNotFound");
This is the one for not found templates. There is a bit of info on it on this issue. The reasoning behind this change is that you can customize the functions that decide whether data is found or not.
Related
I am trying to achieve something pretty simple: load a template and fill it with data. However, the template is rendered several times, and the first time with null data.
I found various posts about the issue stating that rendering occurs every time the subscription adds a record to the clients database, and tried applying proposed solutions, but I still have a first rendering without data. How can I fix that?
Router.configure({
layoutTemplate: 'layout',
loadingTemplate: 'loading',
notFoundTemplate: 'notFound'
});
Router.route('/team/:_id/cal', {
name: 'calendar',
waitOn: function() {
return [
Meteor.subscribe('userTeams',Meteor.user()._id),
Meteor.subscribe('teamUsers', this.params._id)];
},
action : function () {
console.log("action:"+this.ready());
if (this.ready() && Template.currentData != null) {
this.render();
}
},
data: function(){
var team = Teams.findOne({_id:this.params._id})
console.log(JSON.stringify(team));
return team;
}
}
);
Console output
Navigated to http://localhost:3000/team/PAemezbavGEmWBNMy/plan
router.js:33 undefined
router.js:33 {"_id":"PAemezbavGEmWBNMy","name":"superteam","createdAt":"2015-10-22T11:51:10.994Z","members":["T6MpawQj75J2HgPi6","4T3StXAaR9iF4sK99","dDe2dJq3wjL2rFB43"]}
router.js:26 action:true
router.js:33 {"_id":"PAemezbavGEmWBNMy","name":"superteam","createdAt":"2015-10-22T11:51:10.994Z","members":["T6MpawQj75J2HgPi6","4T3StXAaR9iF4sK99","dDe2dJq3wjL2rFB43"]}
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.
I am using Meteor 1.0
I have the following code :
/lib/collections.js
Members = new Mongo.Collection('members');
/lib/router.js
Router.configure({
layoutTemplate: 'layout',
loadingTemplate: 'loading',
notFoundTemplate: 'notFound',
waitOn: function() { return Meteor.subscribe('members'); }
});
Router.route('/', {name: 'menu'});
Router.route('/member/new/', {name: 'memberNew'});
Router.route('/member/renew/', {name: 'memberRenewal'});
/server/publications.js
Meteor.publish('members', function() {
console.log("Publishing....");
return Members.find();
});
/client/templates/memberList.js
Template.membersList.helpers({
listMembers: function() {
return members.find().fetch(); >>>>>> Error line
}
});
I get the following error:
Exception in template helper: ReferenceError: members is not defined
at Object.Template.membersList.helpers.listMembers
(http://meteorvb.dhcp.meraka.csir.co.za:3000/client/templates/membersList.js?
I have removed autopublish bit if I change /client/templates/memberList.js to read
Template.membersList.helpers({
listMembers: function() {
return Members.find().fetch();
}
});
Everything works.
Can anyone please help me?
I think it's just a typo where you have used lowercase m instead of upper case M for Members.
Template.membersList.helpers({
listMembers: function() {
return Members.find().fetch(); >>>>>> Error line
}
});
Variables are case sensitive and since the members collection was assigned to "Members" you need to refer it as "Members" elsewhere.
Members = new Mongo.Collection('members');
I have a small meteor app going with iron router. Here's my routes.js, which is available to both client and server:
Router.configure({
layoutTemplate: 'defaultLayout',
loadingTemplate: 'loading'
});
// Map individual routes
Router.map(function() {
this.route('comicCreate', {
path: '/comic/create'
});
this.route('comicDetails', {
onBeforeAction: function () {
window.scrollTo(0, 0);
},
path: '/comic/:_id',
layoutTemplate: 'youtubeLayout',
data: function() { return Comics.findOne(this.params._id); }
});
this.route('frontPage', {
path: '/',
layoutTemplate: 'frontPageLayout'
});
this.route('notFound', {
path: '*',
where: 'server',
action: function() {
this.response.statusCode = 404;
this.response.end('Not Found!');
}
});
});
I need to feed some fields from my comic collection document into a package that wraps Youtube's IFrame API, and I'm doing this via the rendered function:
Template.comicDetails.rendered = function() {
var yt = new YTBackground();
if (this.data)
{
yt.startPlayer(document.getElementById('wrap'), {
videoIds: this.data.youtubeIds,
muteButtonClass: 'volume-mute',
volumeDownButtonClass: 'volume-down',
volumeUpButtonClass: 'volume-up'
});
}
};
This works great when I start by going to localhost:3000/ and then clicking on a link set to "{{pathFor 'comicDetails' _id}}". However, if I go directly to localhost:3000/comic/somevalidid, it doesn't, despite the fact that both routes end up pointing me at the same url.
The reason appears to be that when I go directly to the deep link, "this.data" is undefined during the execution of the rendered function. The template itself shows up fine (data correctly replaces the spacebars {{field}} tags in my template), but there's nothing in the "this" context for data when the rendered callback fires.
Is there something I'm doing wrong here?
try declaring the route in Meteor.startup ... not sure if that's the problem but worth a try
I set up my router so that if someone types in sitename.com/:username, it goes directly to that users page. But for some reason, when I attempt to do this I sometimes get redirected to my home page and get this error in the console.
Sorry, couldn't find the main yield. Did you define it in one of the rendered templates like this: {{yield}}?
It's even more strange because I would say 60% of the time it loads fine and there are no issues. Does anyone familiar with Meteor, Handlebars, and the Iron-Router package know about this or can help?
If you need more code let me know.
Here is the routing. I added the wait() call at the end to see if that would help. It seems to have helped a bit but the error still occurs.
this.route('userPosts', {
path: '/:username',
layoutTemplate: 'insideLayout',
template: 'userPosts',
yieldTemplates: {
'insideNavigationList': {to: 'list'},
'brandContainer': {to: 'brand'},
'postsPageOptions': {to: 'pageOptions'}
},
waitOn: function () {
return [Meteor.subscribe('userData'), Meteor.subscribe('selectedUser', this.params.username), Meteor.subscribe('posts', this.params.username)];
},
data: function () {
return Meteor.users.findOne({username: this.params.username}) && Session.set('selectedUserId', Meteor.users.findOne({username: this.params.username})._id)
},
before: function () {
if (!Meteor.user()) {
this.redirect('/login')
}
this.subscribe('selectedUser', this.params.username).wait();
this.ready();
}
});