Is my router.js is correct? - ember.js

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

Related

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.

Nested routes in Ember

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'});
});
});
});

How do I do a "needs" on a nested controller for emberjs?

I have the following router:
this.resource('foo', {path: '/foo'}, function() {
this.resource('foo.bar', {path: '/bar'}, function() {
this.route('wat', {path: '/wat'});
});
});
My FooBarWatController is a singleton and I need access to the FooBarController's model. What does the needs look like for FooBarWatController to have access to the FooBarController?
FooBarWatContoller = Ember.ObjectController.extend({
needs: ['?'],
action: {
something: function() {
console.log(this.get('controllers.?.model').get('id'));
}
}
});
FooBarWatContoller = Ember.ObjectController.extend({
needs: ['foo/bar'],
action: {
something: function() {
console.log(this.get('controllers.foo/bar.model').get('id'));
}
}
});

Ember + Ember Data Route error handling issue

In soume routes in my app error action is never triggered and I can't figure out why. On some Routes error action works fine.
This is application route:
Simitu.ApplicationRoute = Ember.Route.extend({
init: function() {
this._super();
Simitu.AuthManager = Simitu.AuthManager.create();
},
model: function() {
if (Simitu.AuthManager.get('session.user'))
return this.store.find('admin', Simitu.AuthManager.get('session.user'));
},
actions: {
error: function(reason, transition) {
if (reason.status === 401) {
Simitu.AuthManager.reset();
this.transitionTo('login');
}
}
}
});
On this route Error is never triggered:
Simitu.PlacesIndexRoute = Ember.Route.extend({
model: function() {
var self = this;
// force adapter request
this.store.find('place');
return this.store.filter('place', function(record) {
// return just places that belongs to this client / application
return record.get('client_id') === self.modelFor('client');
});
},
actions: {
createNew: function() {
var place = this.store.createRecord('place');
// tree structure in places is not implemented yet
//parent = this.store.find('place', params.place_id);
place.set('client_id', this.modelFor('client'));
// open place
this.transitionTo('place', place);
},
error: function(error, transition) {
return true;
}
}
});
And on this Route everything works just fine:
Simitu.ClientsRoute = Ember.Route.extend({
model: function() {
return this.store.find('client');
},
actions: {
error: function() {
return true;
}
}
});
Have anybody some ide why?
The error action is fired on the resource, not an individual route.
http://emberjs.jsbin.com/cayidiwa/1/edit
This is how my router looks like. Maybe it breaks because of the nesting or filter logic in models. I fixed it in beforeModel hook in routes but still have not clue what is wrong with my first solution.
Simitu.Router.map(function () {
this.resource('login');
this.resource('clients');
this.resource('client', { path: 'clients/:client_id'}, function() {
this.resource('places', function() {
this.resource('place', { path: ':place_id' });
});
this.resource('placecategories',{ path: 'places-categories' }, function() {
this.route('new');
});
});
});
I move some of auth handling logic to beforeModel hook.
Simitu.AuthRoute = Ember.Route.extend({
beforeModel: function(transition) {
if (!Simitu.AuthManager.isAutenticated()) {
this.redirectToLogin(transition);
}
},
redirectToLogin: function(transition) {
this.transitionTo('login');
},
actions: {
error: function(reason, transition) {
if (reason.status === 401) {
Simitu.AuthManager.reset();
this.redirectToLogin(transoition);
}
}
}
});

ember router v2 goBack functionality

In router V1 you can make a simple goBack functionality like this:
App.Router = Ember.Router.extend({
root: Ember.Route.extend({
index: Ember.Route.extend({
route: '/',
redirectsTo: 'posts'
}),
posts: Ember.Route.extend({
route: '/posts',
showPost: Ember.Route.transitionTo('post'),
connectOutlets: function(router){
router.get('applicationController').
connectOutlet('posts',App.Post.find());
}
}),
post: Ember.Route.extend({
route: '/posts/:post_id',
goBack: Ember.Route.transitionTo('posts'),
connectOutlets: function(router, post) {
router.get('applicationController').connectOutlet('post', post);
}
})
})
});
I'm trying to do the same thing in router v2 and came up with the following solution:
App.ApplicationController = Ember.Controller.extend({
currentPathDidChange: function () {
this.set('_previousPath', this.get('_currentPath'));
this.set('_currentPath', this.get('currentPath'));
}.observes('currentPath')
});
App.GobackRoute = Ember.Route.extend({
redirect: function (model) {
var previousPath = this.controllerFor('application').get('_previousPath');
var parts = previousPath.split(".");
var router = this.get('router');
if (router.hasRoute(parts[parts.length - 1])) {
this.transitionTo(parts[parts.length - 1]);
} else if (router.hasRoute(parts[parts.length - 2] + "." + parts[parts.length - 1])) {
this.transitionTo(parts[parts.length - 2] + "." + parts[parts.length - 1]);
} else {
Ember.Logger.warn('No route for: %s', previousPath);
}
}
});
Isn't there a much simpler solution to this?
jsFiddle
I would like to reuse the routes, controllers, etc... without resulting in some sort of spaghetti routing like
App.AnimalsRoute = Ember.Route.extend({
events: {
goBackToThis: function() {
this.transitionTo('this');
},
goBackToThat: function() {
this.transitionTo('that');
},
goBackToSomeThingElse: function() {
this.transitionTo('someThingElse');
}
}
});
I would like to have 1 goback functionality for the whole router!
My initial solution result in something like the following: (look for all the goBack routes, and the reuse of the ebed routes)
App.Router.map(function (match) {
this.route('home', { path: '/' });
this.route('logout');
this.route('login');
this.resource('goBack', { path: '/goback' });
this.resource('ccpr', function () {
this.resource('goBack', { path: '/goback' });
this.resource('ccprPatients', { path: '/' }, function () {
this.route('search');
});
this.resource('ccprPatient', { path: '/:ccpr_patient_id' }, function () {
this.resource('goBack', { path: '/goback' });
this.resource('ccprPracticeSessions', { path: '/practicesessions' }, function () {
});
this.resource('ccprPracticeSession', { path: '/practicesessions/:ccpr_practicesession_id' }, function () {
this.route('info');
this.route('anamnese');
this.route('medication');
this.route('trainingModel', { path: '/trainingmodel' });
this.route('socialEvaluation', { path: '/socialevaluation' });
this.route('medicalFollowUp', { path: '/medicalfollowup' });
this.route('psychologicalEvaluation', { path: '/psychologicalevaluation' });
this.route('nutritionalAdvice', { path: '/nutritionaladvice' });
this.resource('goBack', { path: '/goback' });
this.resource('ebedMedication', { path: '/ebedmedication/:ebed_medication_id' }, function () {
});
this.resource('ebedLabResult', { path: '/ebedlabresult/:ebed_labresult_id' }, function () {
});
this.resource('ebedDietContact', { path: '/ebeddietcontact/:ebed_dietcontact_id' }, function () {
});
this.resource('ebedNutritionBmi', { path: '/ebednutritionbmi/:ebed_nutritionbmi_pkid' }, function () {
});
});
});
this.resource('ccprCardioArticles', { path: "/cardioarticles" });
this.resource('ccprCardiologists', { path: "/cardiologists" });
this.resource('ccprInfoSession', { path: "/infosession" });
this.resource('ccprPatientPresence', { path: "/patientpresence" });
this.resource('ccprPresenceOverview', { path: "/presenceoverview" });
this.resource('ccprNextNutritionalAdvices', { path: "/nextnutritionaladvices" });
});
this.resource('ebed', function () {
this.resource('goBack', { path: '/goback' });
this.resource('ebedMedications', { path: '/ebedmedications' }, function () {
});
this.resource('ebedMedication', { path: '/ebedmedication/:ebed_medication_id' }, function () {
});
this.resource('ebedLabResults', { path: '/ebedlabresults' }, function () {
});
this.resource('ebedLabResult', { path: '/ebedlabresult/:ebed_labresult_id' }, function () {
});
this.resource('ebedDietContacts', { path: '/ebeddietcontacts' }, function () {
});
this.resource('ebedDietContact', { path: '/ebeddietcontact/:ebed_dietcontact_id' }, function () {
});
this.resource('ebedNutritionBmis', { path: '/ebednutritionbmis' }, function () {
});
this.resource('ebedNutritionBmi', { path: '/ebednutritionbmi/:ebed_nutritionbmi_pkid' }, function () {
});
});
});
Isn't there a nicer way?
Updated JSFiddle example
You can do the same thing in the new router using the events property in the router to define actions. From the guide:
If the action is not found on the current controller, it will bubble
up to the current route handler. From there, it will bubble up to
parent route handlers until it reaches the application route.
In your example you need to define the goBack action in the parent of your animals.dog and animals.cat routes;
App.AnimalsRoute = Ember.Route.extend({
events: {
goBack: function() {
this.transitionTo('index');
}
} });
This can be called using the standard {{action}} helper from the template.
<a href='#' {{action goBack}}>Go Back</a>