Controller/route conventions for nested routes in ember - javascript

I have this resource with a nested route in my ember app:
router.js:
Router.map(function() {
this.resource('posts', function () {
this.route('show', {path: '/:id'});
});
});
What is the convention in ember for my controllers? Do I create a separate file for each URL, or does the show handler go in /controllers/posts.js? Or is there perhaps multiple correct ways of doing this?
This is what I have so far in /routes/posts.js:
import Ember from 'ember';
var PostsRoute = Ember.Route.extend({
model: function() {
return posts;
}
});
var posts = [
{
id: '1',
title: 'Object nr one',
content: 'This is the content of Object nr one.'
},
{
id: '2',
title: 'Obelix',
content: 'A fat gaul. From a comic book.'
},
{
id: '3',
title: 'Werner',
content: 'Wat soek werner hier? Dis mos nou belaglik man.'
}
];
export default PostsRoute;
And this is /controllers/posts.js:
import Ember from "ember";
export default Ember.ArrayController.extend({});
I would appreciate if someone showed me the correct way of doing things in this example.. I'm really struggling to find proper examples on the web.
Please note that I'm using ember CLI

"Show handler" never goes to controller file, it's rather a Route. You create separate route, controller, template for each of your resource or route directives. You can tell controller that it should have the same behaviour as other controller, or use a mixin. For example:
router.coffee:
#resource 'training', ->
#route 'chest'
#route 'shoulders'
Means you need following structure:
app/routes/training[your parent resource]/chest.js[your child route]
app/routes/training/shoulders.js
If you need controller for each of this routes you would need files with following paths:
app/controllers/training/chest.js
app/controllers/training/shoulders.js
And templates:
app/templates/training/chest.js
app/templates/training/shoulders.js
It's because I've defined training as resource(parent) and routes as its children.
If you use Ember CLI you can use commands like:
ember g controller training/shoulders
or:
ember g route training/shoulders
Last command will generate you: Route, template and entry in router.js. You can use this commands so you won't have worry too much about your directory structure.
However, it's important to remember that when you define resource inside a resource - child resource isn't really a child and it shouldn't be placed inside parent resource directory. For example:
#resource 'tracks', ->
#resource 'track', path: '/track/:track_id', ->
#route 'edit'
Means you need 2 directories to store route files:
app/routes/tracks/
index.js
app/routes/track/
edit.js
Instead of app/routes/tracks/track/edit.
So, in your example, for following router:
Router.map(function() {
this.resource('posts', function () {
this.route('show', {path: '/:id'});
});
});
app/routes should look like this:
app/routes:
- posts.js # main route for whole resource
- posts/ # directory which contains files for routes inside posts resource
- show.js # posts/show route

Related

How to structure router.js file in VueJs?

I want to structure my router.js file as currently there is around 500 lines of code in it.
{
path: "/",
component: () => import("./../src/views/dashboard/Dashboard.vue"),
meta: {
auth: true,
title: "Dashboard"
}
},
{
path: "/regionWiseDashboard",
component: () => import("./../src/views/dashboard/RegionWiseDashboard.vue"),
meta: {
auth: true,
title: "Dashboard"
}
},
The above code is repeating for every component I include in my project which just makes the code look more and more unreadable. Can I structure it anyhow? Maybe put all files in an JSON or divide the main js file into children js files?
How I structured my routes in vue.
First: create a folder named routes, inside this folder, create subfolders depends on how you group your routes. Example, villages, dashboard, user
Second: create a main route inside your routes folder. This main route will hold and import all your routes made in villages, dashboard, user.
last: import this main route to your main app.js

Ember js routing not working in 2.10

I was using this Ember route file to map this URI www.example.com/home/page with the template main-page.hbs located in the home folder
export default {
resource: 'home',
path: '/home',
map() {
this.route('main-page', { path: 'page' });
}
};
I was working fine as well until I upgraded my application from 1.2.0 to 2.1.0. I didn't find any difference in two versions with respect to routing in the documentation.Is there any change in routes documentation? Am, I doing something wrong? I am a newbie in Ember js and founding it difficult to understand the routing documentation
Full source code for the plugin is available # github
and I am using the discourse application
Here is an example of the current syntax of the router.js
I'm unsure of the specifics of your situation, but hopefully this will help.
import Ember from 'ember';
import config from './config/environment';
const Router = Ember.Router.extend({
location: config.locationType,
rootURL: config.rootURL
});
Router.map(function() {
// note the implicit 'application' route with {{outlet}}
this.route('main-page', { path: '/home' ); // or '/' to make it the root
this.route('rainbow', function() {
this.route('red');
this.route('orange');
// ... nested
this.route('vampire');
});
export default Router;
https://guides.emberjs.com/v2.1.0/routing/defining-your-routes/

EmberJS 2 route dynamic segment in not nested routes undefined

Really new to ember and trying to setup basic (in my mind) routes.
I have calendars resource and I want to display individual calendars.
My app/router.js has the following:
this.route('calendar', {path: 'calendars/:calendar_id'}, function () {
this.route('show');
this.route('edit');
});
this.route('calendars', function(){
this.route('create');
});
Folders are as following:
app/routes: [
calendars: [create, index],
calendar: [edit, show]
]
app/templates: [
calendars: [create, index]
calendar: [edit, show]
]
In app/routes/calendar/show.js:
import Ember from 'ember';
export default Ember.Route.extend({
model(params) {
return this.store.findRecord('calendar', params.calendar_id);
}
});
Problems start when I go to http://SERVER/calendars/5/show (5 is a :calendar_id part, SERVER is what hosts ember app) :
when I log params - they are undefined
In dev tools I see that Ember somehow makes a POST request to my server as http://SERVER/calendars/5
(a :calendar_id part, SERVER is on same domain and where my back-end resides).
This happens regardless if I comment out model() function in app/routes/calendar/show.js file.
Apparently Ember knows what calendar_id to use for that request.
But I don't know where that call to the server happens:
If I comment out model(){} altogether, my template renders model record (the calendar record that Ember fetches).
If I on the other hand try to log params in model() and I comment out this.store.findRecord part out, the params are undefined and it raises an error.
I thought at first that it is my DS.RESTAdapter since I have defined updateRecord changes to fake PUT request (my server does not allow that), but I commented out the whole file and it still does this query.
I've cleaned both dist/, tmp/, upgraded to 2.9.0, but it does the same thing.
I have no controllers defined
How does Ember make POST request if model() hook is missing from route, I have no controllers difined. Also how do I fix it so that it works? ;p
Edit [2]:
I am trying this now and I think it kinda works, but looks ugly:
this.route('calendars',{ path: '/calendars'}, function(){
this.route('create');
});
this.route('calendar', { path: '/' }, function () {
this.route('show', { path: '/calendars/:calendar_id/show' });
this.route('edit', { path: '/calendars/:calendar_id/edit' });
});
this.route('index', { path: ''});
Ember is smart enough to generate a default route if you do not create one, and a default model if you do not create a model function.
It does this based on the routes name ie if your route is "calendar" it generates a model function based on the "calendar" model.
Try explicitly define your route path with the parameters as per ember docs:
https://guides.emberjs.com/v2.9.0/routing/defining-your-routes/
this.route('calendar', function () {
this.route('show', { path: '/:calendar_id/show' });
this.route('edit', { path: '/:calendar_id/edit' });
this.route('create');
});

Meteor JS Iron Router, route sub directory

I am working on a admin and client portal in Meteor JS using Iron:Router.
I know i can create a route using:
this.route('tasks',{path:'/projects', layoutTemplate: 'adminLayout'});
But is it possible to make a route with a sub directory such as:
this.route('tasks',{path:'/admin/projects', layoutTemplate: 'adminLayout'});
So that way i can also have a sub directory of:
this.route('/admin/projects', {name: 'admin.projects', template: 'projects', layoutTemplate: 'adminLayout'}
and
this.route('/client/projects', {name: 'client.projects', template: 'projects', layoutTemplate: 'adminLayout'}
Thanks for any input.
All the paths you have can coexist in one app quite happily.
The router (or your browser) doesn't have any concept of directories/subdirectories, all it understands are strings and regular expressions. The nesting is purely something we (should) create to enable ourselves to understand how an app/api(/codebase, etc) is structured.
As Sasikanth points out that is not the full error message. However looking at packages/iron_middleware-stack/lib/middleware_stack.js line 31 it's easy to confirm what is happening:
throw new Error("Handler with name '" + name + "' already exists.");
This is within the Router.route function, which is documented here.
Router.route('/post/:_id', {
// The name of the route.
// Used to reference the route in path helpers and to find a default template
// for the route if none is provided in the "template" option. If no name is
// provided, the router guesses a name based on the path '/post/:_id'
name: 'post.show',
// To support legacy versions of Iron.Router you can provide an explicit path
// as an option, in case the first parameter is actually a route name.
// However, it is recommended to provide the path as the first parameter of the
// route function.
path: '/post/:_id',
// If we want to provide a specific RouteController instead of an anonymous
// one we can do that here. See the Route Controller section for more info.
controller: 'CustomController',
// If the template name is different from the route name you can specify it
// explicitly here.
template: 'Post',
// and more options follow
So for the code you included above, you provide explicit paths. Therefore the first parameter is the route name. These must be unique as they are used to lookup the path in the pathFor, urlFor and linkTo helpers. As you are not providing an explicit template option, the name is also used for that, but your code is throwing this exception before it gets that far.
I think what you were trying to achieve is this:
this.route('/projects', {name: 'projects', template: 'tasks', layoutTemplate: 'adminLayout'});
this.route('/admin/projects', {name: 'admin.projects', template: 'tasks', layoutTemplate: 'adminLayout'});
this.route('/client/projects', {name: 'client.projects', template: 'tasks', layoutTemplate: 'adminLayout'});

execute code only when the "base" route is activated in emberjs

Is there a way to execute when a "base" route is activated/re-activated? I have the following urls:
Router.map(function() {
// /projects
this.resource('projects', function() {
// /projects/2
this.resource('project', {path: ':id'});
});
});
I'd like to transitionTo the individual project route if there is only one project returned from the projects route. I can do this:
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
return this.store.findAll('project');
},
afterModel: function(projects, transition) {
if (projects && projects.get('length') === 1) {
this.transitionTo('project', projects.get('firstObject'));
}
}
});
This works nicely...except i can still go to the projects route and since the model has already been loaded that hook doesn't fire again. Is there a way to listen to always enforce that rule when the projects route is activated?
For example, if i go to /projects/23 and then i go to /projects i'd like to auto-transition them to the single project route if there is only one. I don't know how to accomplish that since it's a nested route and the activate and afterModel methods have already been fired when visiting /projects/23 for the first time.
Does that make sense? and how can i accomplish this?
Use an index route on your projects resource. It will only get hit when you hit /projects
ProjectsIndex
export default Ember.Route.extend({
model: function() {
var projects = this.modelFor('projects');
if (projects && projects.get('length') === 1) {
this.transitionTo('project', projects.get('firstObject'));
}
},
});

Categories