Nested routes in Ember - ember.js

I want my settings area to look like this:
..
/settings/:accountId/users
/settings/:accountId/users/:userId
I have my router defined as follows:
Router.map(function() {
this.route('login');
this.resource('settings', { path: 'settings/:settings_id' }, function() {
this.route('overview');
this.route('users');
});
});
This works for displaying the users listing page. I'm not sure how to take it to the next step though and have both a route and a resource for /users and /users/1.
Thanks.

In the latest versions of Ember, route's can have sub routes (for namespace sake).
Router.map(function() {
this.route('login');
this.resource('settings', { path: 'settings/:settings_id' }, function() {
this.route('overview');
this.route('users', function(){
this.route('user', {path:':user_id'});
});
});
});
http://emberjs.jsbin.com/cutayuniga/1/edit?html,js,output
If you're in an older version, you will have to make users a resource.
Router.map(function() {
this.route('login');
this.resource('settings', { path: 'settings/:settings_id' }, function() {
this.route('overview');
this.resource('users', function(){
this.route('user', {path:':user_id'});
});
});
});

Related

Is my router.js is correct?

Hi I am getting an error of UnrecognizedUrl when I am trying to access my route on my browser to dashboard/posts/id/comments. Below is my router.js I would like to ask if my router is wrong or can someone please tell me the right approach
this.route('dashboard', function() {
this.route('posts', function() {
this.route('show', { path: ':post_id' }, function() {
this.route('comments', { path: ':post_id/comments'}, function() { });
});
});
});
However if I put the {{outlet}} on my resource file app/pods/dashboard/posts/show/template.hbs it does show the content I put on my app/pods/dashboard/posts/show/comments/template.hbs when I changed my router.js to
this.route('dashboard', function() {
this.route('posts', function() {
this.route('show', { path: ':post_id' }, function() {
this.route('comments');
});
});
});
My goal is I want to show the content of app/pods/dashboard/posts/show/comments/template.hbs on a different page which in the browser url should be dashboard/posts/id/comments
It should be like
this.route('dashboard', function() {
this.route('routeA', function() {
this.route('childRouteA', { path: '/:childRouteA_id' }, function() {
this.route('childRouteAb');
});
});
});
Ex: dashboard/routeA/id/childRouteAb
If childRouteAb is a dynamic id then, it should be like
this.route('dashboard', function() {
this.route('routeA', function() {
this.route('childRouteA', { path: '/:childRouteA_id' }, function() {
this.route('childRouteAb', { path: '/:childRouteAb'});
});
});
});
Ex: dashboard/routeA/id/id2
If you need the url to specify the type of id before the id, you can do like this.
this.route('dashboard', function() {
this.route('routeA', function() {
this.route('childRouteA', { path: '/childRouteA/:childRouteA_id' }, function() {
this.route('childRouteB', { path: '/childRouteB/:childRouteB_id'});
});
});
});
Ex: dashboard/routeA/childRouteA/id1/childRouteB/id2

Ember: object resolving of nested resources

I've recently started using Ember.js with Ember-CLI and I'm pretty excited.
But there are some things that are not clear for me.
Here is my router:
this.resource("authenticated", { path: '/' }, function() {
this.resource("contacts", function() {
this.resource("contact", { path: ':id' });
});
this.resource("chats", function() {
this.resource("chat", { path: ':id' });
});
this.resource("settings", function() {
this.resource("setting", { path: ':id' });
});
});
The question is - why after 2nd nesting 'resolver' starts finding objects outside of 'authenticated' resource?
For example
my-app/pods/chats/index/view
But expected
my-app/pods/authenticated/chats/index/view
Why is 'authenticated' missed ?
Your authenticated route is not applied in the url because you assigned it's url to the root: { path: '/'}.
You should either change the path to 'authenticated' or remove it all together:
this.resource("authenticated", function() {
...
});
Now, however, authenticated is only rendered when a user navigates to my-app/pods/authenticated. If you still want to render authenticated as index, you should prefix your nested resources:
this.resource("authenticated", { path: '/' }, function() {
this.resource("contacts", { path: '/authenticated/contacts' }, function() {
...
});
this.resource("chats", , { path: '/authenticated/chats' }, function() {
...
});
...
});
I hope this helped you.

Can Ember handle multiple routes to a single resource?

I want to show the profile page on my web app either by username or user_id. I've tried the following with no success, any ideas?
MyApplication.Router.map(function () {
this.resource('user', { path: '/user' }, function () {
this.resource('profile', {path: '/profile/id/:user_id'});
this.resource('profile', {path: '/profile/:user_username'});
});
this.resource('notFound', {path: '/notfound'});
});
It seems Ember shouldn't really be used in this way. I've read through issues 551 and 571 on Embers Github. I think it's best to stick with showing a user by id to avoid working against the framework.
You can merge those two resources into one as follows:
MyApplication.Router.map(function () {
this.resource('user', { path: '/user' }, function () {
this.resource('profile', {path: '/profile/id/:value'});
});
});
MyApplication.ProfileRoute = Ember.Route.extend({
model: function(params) {
var value = params.value;
if (isNaN(value)) {
return this.store.find('user', { username: value });
} else {
return this.store.find('user', value);
}
}
});
If the value in the URL is a number it will do a findById; otherwise it will do a findQuery. Obviously this approach will fail if some username is a number.
If the URL is the important part for you, you could change the resource names and keep the url prefix the same, for example:
MyApplication.Router.map(function () {
this.resource('user', { path: '/user' }, function () {
this.resource('profileByUserId', {path: '/profile/id/:user_id'});
this.resource('profileByUsername', {path: '/profile/:user_username'});
});
this.resource('notFound', {path: '/notfound'});
});
Hope it helps.
May be with nested routes for the profile resource
MyApplication.Router.map(function () {
this.resource('user', { path: '/user' }, function () {
this.resource('profile', function(){
this.route('byid',{path: '/id/:user_id'});
this.route('byname',{path: '/name/:user_username'});
});
});
this.resource('notFound', {path: '/notfound'});
});
But remember to implement serialize for the definition of the route with user_name
http://emberjs.com/guides/routing/defining-your-routes/
The previos aproach is also valid IMHO

Adding a new route to an existing Ember.js app, need input

I have an existing Ember app which works great. I need to add a new subroute to the app to allow users to view additional information. My current route looks like this:
Social.Router.map(function() {
this.resource('accounts', { path: '/accounts' }, function(){
this.resource('account', { path: ':account_id'});
});
});
with the following URL
#/accounts/56/
The route I'd like to add is this:
#/accounts/56/interactions
So I added a nested route like so:
Social.Router.map(function() {
this.resource('accounts', { path: '/accounts' }, function(){
this.resource('account', { path: ':account_id'}, function(){
this.route('interactions', { path: '/interactions'});
});
});
});
But when that route is accessed I get the following error:
Uncaught Error: assertion failed: The route interactions was not found core.libs.js:2236
Uncaught Error: You cannot modify child views while in the inBuffer state core.libs.js:19298
So I also added an empty InteractionsRoute but that didn't resolve it:
Social.InteractionsRoute = Ember.Route.extend();
Does anyone have input on what might be going wrong?
In addition I'm trying to add a button to the interface which looks like this:
{{#linkTo "interactions"}}# Interactions{{/linkTo}}
Social.Router.map(function() {
this.resource('accounts', { path: '/accounts' }, function(){
this.resource('account', { path: ':account_id'}, function(){
this.route('interactions', { path: '/interactions'});
});
});
});
Like this the URL to interactions is #/interactions
But you wanted this: #/accounts/56/interactions
Therefore you need to remove the preceding slash in the path hook of interactions, otherwise you'll indicate that this route will be accessed from the root.
Social.Router.map(function() {
this.resource('accounts', { path: '/accounts' }, function(){
this.resource('account', { path: ':account_id'}, function(){
this.route('interactions', { path: 'interactions'});
});
});
});
By the way, if you don't declare a path hook the url will be the same as the route name. So you can also use this:
Social.Router.map(function() {
this.resource('accounts', function(){
this.resource('account', { path: ':account_id'}, function(){
this.route('interactions');
});
});
});
Try splitting out your list from the individual record view.
Social.Router.map(function() {
this.resource('accounts');
this.resource('account', { path: '/accounts/:account_id' }, function() {
this.route('interactions');
});
});
Your route name for interactions should be like this:
Social.AccountInteractionsRoute = Ember.Route.extend();
From the table on http://emberjs.com/guides/routing/defining-your-routes/
If all else fails you could just avoid the nested resources and define the paths for each route.
Social.Router.map(function() {
this.resource('accounts');
this.resource('account', { path: '/accounts/:account_id' });
this.resource('account-interactions', { path: '/accounts/:account_id/interactions' });
});

How do I retrieve the path of a route?

Given the following Router setup:
App.Router.map(function() {
this.resource('posts', function() {
this.route('new');
this.resource('post', { path: ':post_id' }, function() {
this.route('edit');
});
});
});
Is it possible to obtain the path of a route?
Fictitious example:
App.Router.get('path', 'posts.new'); //=> "/posts/new"
Or with a model like:
App.Router.get('path', 'post.edit', model); //=> "/posts/1/edit"
Try this in your console/dev tools:
App.Router.router.generate(['posts.new']);
this should output:
/posts/new
And with a model:
App.Router.router.generate(['post.edit'], postModel);
will output
/posts/1/edit
Thanks to #MilkyWayJoe's reference! https://github.com/emberjs/ember.js/blob/master/packages/ember-routing/lib/helpers/link_to.js#L112-L117 :)