Meteor: IronRouter does not trigger notFound rule - javascript

I would like my Meteor app to use IronRouter for client-side routing.
My routing code looks as follows:
Router.map(function() {
this.route('story', {
path: '/story/:_id',
data: function() {
return Stories.findOne({displayId: +this.params._id});
},
notFound: 'storyNotFound'
});
});
I have 2 templates corresponding to this route:
<template name="story">
Welcome to story: {{this.displayId}}.
</template>
<template name="storyNotFound">
Story not found
</template>
Problem: the 'storyNotFound' template is never rendered, not even when
Stories.findOne({displayId: +this.params._id})
returns undefined.
Instead, the 'story' template is rendered with the text "Welcome to story: ".
What am I missing?

Have you tried replacing notFound: with notFoundTemplate ? The Iron Router example uses notFound but I could only find notFoundTemplate in the source code and that worked for me.
Router.map(function() {
this.route('story', {
path: '/story/:_id',
data: function() {
return Stories.findOne({displayId: +this.params._id});
},
notFoundTemplate: 'storyNotFound'
});
});

Related

How do I supply an index route with a template Ember 2?

I want to create an ember application as follows:
var app = Ember.Application.create({
rootElement: document.getElementById('root'),
name: 'my-application',
IndexRoute: Ember.Route.extend({
model: function() {
console.log('model');
},
afterModel: function(model, transition) {
},
template: Ember.Handlebars.compile('<div id="test"></div>'),
}),
locationType: 'hash',
});
The problem is that I dont get the test div in the DOM. How come?
http://jsbin.com/koyihapuze/edit?html,js,console,output
1) in your code this.namespace.TEMPLATES is undefined ( inside resolver ) so you
Fix code like
resolveTemplate: function(parsedName) {
var templatePath = parsedName.fullNameWithoutType.replace('.', '/');
var template = this.namespace.TEMPLATES && this.namespace.TEMPLATES[templatePath];
if (!template) {
template = this._super(parsedName);
}
return template;
},
After you'll find new div.ember-view element inside application container
2) template is not property of route ( as in your code ), you can define ApplicationView with template or templateName in router and solve resolver errors
P.S. It's better to start with Ember using ember-cli

Meteor.js Iron Router and similar or dynamic routes

I am trying to build dynamic routes for an admin section on my site so that "/admin" would work as well as "/admin/users" and "/admin/users/add" and so on. I have tried some different combinations but still struggling with this. Below is what I've tried and in different orderes.
Ideally if I could just specify "/admin" but dynamically reference each new / as an argument that would be best for handling in the code. Example "/admin/1/2/3/4/5" and being able to reference the 1 2 3 etc. I didn't see anything like this in the docs though.
Router.route('/admin', {
name: 'admin',
path: '/admin',
template: 'admin',
layoutTemplate: 'layout_admin',
action: function() {
Session.set('apage', 'dashboard');
Session.set('asect', null);
this.render();
}
});
// Not Working...
Router.route('/admin/:apage', {
name: 'admin',
path: '/admin/:apage',
template: 'admin',
layoutTemplate: 'layout_admin',
action: function() {
Session.set('apage', this.params.apage);
Session.set('asect', null);
this.render();
}
});
// Not Working...
Router.route('/admin/:apage/:asect', {
name: 'admin',
path: '/admin/:apage',
template: 'admin',
layoutTemplate: 'layout_admin',
action: function() {
Session.set('apage', this.params.apage);
Session.set('asect', this.params.asect);
this.render();
}
});
EDIT (Answered)
After some testing it seems calling a template should be (or easiest done) in the this.render() line and the routes should go from most restrictive/detailed to least - which I did try before. The problem seems to be using this.params on the template: line. This solution is not perfect but posting for anyone who may run into a similar problem. As far as further variables in the url like "/admin/1/2/3/4/5" it seems they would need additional routes and can't be fully dynamic as a "/" can not go into the params and the router would look for a route and return notFound unless you can an explicit matching route. There may be a work around that I did not find.
Working code below:
Router.route('adminPage', {
path: '/admin/:asect/:apage',
template: 'admin',
layoutTemplate: 'layout_admin',
action: function() {
Session.set('asect', this.params.asect);
Session.set('apage', this.params.apage);
this.render('admin_' + this.params.asect + '_' + this.params.apage);
}
});
Router.route('adminSect', {
path: '/admin/:asect',
template: 'admin',
layoutTemplate: 'layout_admin',
action: function() {
Session.set('asect', this.params.asect);
Session.set('apage', null);
this.render('admin_' + this.params.asect);
}
});
Router.route('admin', {
path: '/admin',
template: 'admin',
layoutTemplate: 'layout_admin',
action: function() {
Session.set('asect', 'dashboard');
Session.set('apage', null);
this.render('admin_dashboard');
}
});
There is a way to have optional parameters in routes (which is what you're looking for unless I'm mistaken). With that in mind, you should be able to manage using one router.
Router.route('admin',{
path: '/admin/:asect?/:apage?',
template: 'admin',
layoutTemplate: 'layout_admin',
action: function() {
var asect = this.params.asect || 'dashboard',
apage = this.params.apage || null,
render = (function(){
if(apage !== null) {
return 'admin_'+ asect +'_'+ apage;
} else {
return 'admin_'+ asect;
}
})();
Session.set('asect', asect);
Session.set('apage', apage);
this.render(render);
}
});
The ? after each parameter in the path designates it as an optional parameter. You should be able to then check if it has been defined or otherwise assign a default value and then structure your view and session accordingly.
Note: You can test in this MeteorPad - just update the URL according to the names of the example templates.
http://meteorpad.com/pad/Ri4Np5xDJXyjiQ4fG

Naming of Routes for nested resources in Ember.JS

The following route setup is from the Ember.JS docs (http://emberjs.com/guides/routing/defining-your-routes/) and I have to deal with an equivalent problem:
App.Router.map(function() {
this.resource('post', { path: '/post/:post_id' }, function() {
this.route('edit');
this.resource('comments', function() {
this.route('new');
});
});
});
According to the docs and my own experience this results, among others, in the following route:
/post/:post_id/comments -> App.CommentsIndexRoute
However, since I want a post-specific comment route I would have expected
/post/:post_id/comments -> App.PostsCommentsRoute
What exactly is my fallacy and what would I have to change to achieve my goal.
Only route's share their name with their parent resource. If you wanted it to show up as as PostsCommentsRoute it would be more like this (note I pluralized it to match your example, despite the url not being pluralized)
App.Router.map(function() {
this.resource('posts', { path: '/post/:post_id' }, function() {
this.route('comments');
});
});

Ember.js Error in specifying URL type of location='history' in App.Route

I have started learning the ember.js framework and I am stuck at how to use the setting of the URL type feature that the framework has.
http://emberjs.com/guides/routing/specifying-the-location-api/
I have this simple application.js
App = Ember.Application.create();
App.Router.reopen({
location: 'history'
});
App.Router.map(function () {
this.route('about');
});
App.ApplicationRoute = Ember.Route.extend({
model: function () {
return appdata;
}
});
App.IndexRoute = Ember.Route.extend({
setupController: function (controller) {
// Set the IndexController's `title`
controller.set('indextitle', "My Index title");
},
renderTemplate: function () {
this.render({ outlet: 'indexoutlet' });
}
});
App.AboutRoute = Ember.Route.extend({
model: function () {
return appdata;
},
renderTemplate: function () {
this.render({ outlet: 'aboutoutlet' });
}
});
var appdata = { mytext: '', theplaceholder: 'Enter new text', attr:'Yeap!' }
If I don't use the
App.Router.reopen({
location: 'history'
});
the application works fine and it goes to the 'about' route by appending the URL the '~/EmberjsTest.aspx#/about' as it supposed to do.
However because I do not like the hash symbol in the URL of the page, I would prefer if it was removed and to do that the guide says we should put this code:
App.Router.reopen({
location: 'history'
});
But when I do it I get an error in the Chrome console saying:
'Assertion failed: The URL '/EmberjsTest.aspx' did match any routes in your application'
What am I doing wrong?
Thanks in advance
If you want to use the history API then you have two options.
Serve your Ember app from '/' so that Ember can just work with it's "normal" index/root route.
Create a route in your Ember app that can handle '/EmberjsTest.aspx'.
this.route("index", { path: "/EmberjsTest.aspx" });
Note that if you go with option 2 you'll probably have to update all of your routes to include '/EmberjsTest.aspx' in their paths.
this.resource("posts", {path: "/EmberjsTest.aspx/posts" })

Ember.js: Template type not defined?

The user is being correctly routed by the main router to the App.IndexRoute below:
App.IndexRoute = Ember.Route.extend({
model: function() {
return App.Contact.find();
},
init: function() {console.log('were in the indexroute! ive been created.')},
controller: 'index',
setupController: function(controller) {
controller.set('content', App.Contact.find());
console.log('the IndexController is set up, with the model equal to ' + controller.get('content') + '.');
},
renderTemplate: function() {
this._super();
this.render('contacts', {
outlet: 'sidebar',
into:'index',
controller: 'contacts'
});
this.render('map', {
into: 'index',
outlet: 'map', //cannot connect outlet yet, acc. GitHub ember-data gist #1838
controller: 'map'
});
}
});
But the index page refuses to load any of the dynamic, Handlebars-defined content. Removing this._super() from the renderTemplate function yields a Type Error, with 'connectOutlet' not defined. I'm getting the comments in the Handlebars templates on the index page (hidden, of course), so I know they're loading correctly.
Can anyone spot any issues with the route definition? If not, I'll have to delve further. Any advice would be much appreciated.
Notes: Ember, ruby, rails and so on all up-to-date as of writing. Chrome console debugger gives:
DEBUG: Ember.VERSION : 1.0.0-rc.1 ember.js:348
DEBUG: Handlebars.VERSION : 1.0.0-rc.3 ember.js:348
DEBUG: jQuery.VERSION : 1.9.1

Categories