What is the difference between route and path in EmberJs
Router.map(function () {
this.route('about');
this.route('contact', { path: '/getting-in-touch' });
});
The first argument to route is the name of the route. It's used to find the right files to load app/routes/about.js and to provide links <LinkTo #route="about">About</LinkTo>. If you provide a path option it is used to create the URL you see in the location bar for the browser.
From the ember guides
You can leave off the path if it is the same as the route name.
For your case the following are equivalent:
Router.map(function () {
this.route('about', { path: '/about' });
this.route('contact', { path: '/getting-in-touch' });
});
Router.map(function () {
this.route('about');
this.route('contact', { path: '/getting-in-touch' });
});
Will results in Ember knowing how to load URLs for https://yoursite.com/about and https://yoursite.com/getting-in-touch
And for <LinkTo #route="contact">Contact Us</LinkTo> to create a link with HTML like Contact Us
Related
In my router.js file, I have something that looks like the following
import EmberRouter from '#ember/routing/router';
const Router = EmberRouter.extend({});
Router.map(function () {
this.route('index', { path: '/' });
this.route('foo', function() {
this.route('bar', function() {
this.route('cat');
});
});
this.route('notfound', { path: '/*path' });
});
export default Router;
The problem is that I want the path /foo/bar/cat to route to the foo.bar.cat route, but I don't want the paths /foo or /foo/bar to route to anything except a 404. In my case, the foo and bar routes are essentially useless. I just want the url to have 3 levels for aesthetic purposes.
I actually realized what made more sense was to just avoid creating foo and bar routes and create a path for the route I wanted.
So instead of doing this in ember-cli:
ember g route foo/bar/cat
I just did
ember g route cat
And then I set the desired path in the router.
Router.map(function () {
this.route('index', { path: '/' });
this.route('cat', { path: '/foo/bar/cat'});
this.route('notfound', { path: '/*path' });
});
That gives me the correct route for foo/bar/cat, but foo and foo/bar both get routed to the notfound route.
Here is my problem,
assume I am having an ember app with following ember route configuration:
Router.map(function() {
this.route('todos', function() {
this.route('new');
this.route('view', {
path: "/:id"
});
});
this.route('articles', function() {
this.route('view', {
path: "/:id"
});
this.route('new');
});
});
Now i want to add the add the prefix for each route based on some user information i would be fetching.
For eg:
Below are the two user information
dev = {
id: 1,
workspace: 'DEV'
}
qa = {
id: 2,
workspace:'TEST'
}
once the dev is landing in the app, route must be like:
todos:
/DEV/todos/new
and same for the other users.
once the qa is landing in the page, route must be like:
/TEST/todos/new
to solve this i know we generate the parent route and add all the other route as child, need to change the file structure for this case.
Here is Ember :
ember-cli: 2.13.3,
ember-data: 2.18.5
This is straight forward in Ember.js using the router's path as URL paths can be customized easily.
For your case, the todos route should have a dynamic segment (say, workplace) and hence, the router entry will be like:
Router.map(function() {
this.route('todos', { path: '/:workplace/todos' }, function() {
this.route('new');
...
});
});
And if you are transitioning to new todo page using this.transitionTo('todos.new', 'TEST'), then URL will be updated as TEST/todos/new.
This twiddle has a tiny demo. Hope that helps :)
I have a route defined as:
Router.map(function() {
this.route('folder', { path: '/f/:path' }, function() {} );
});
And the route itself as:
export default Ember.Route.extend({
model(params) {
const path = params.path;
console.log(`path=${ path }`);
return path;
}
});
Currently:
http://localhost:4200/f/folder
works but
http://localhost:4200/f/folder/subfolder
throws a Uncaught UnrecognizedURLError {message: "/f/folder/subfolder", name: "UnrecognizedURLError"} since the router is expecting me to define a route at each level.
Use case is the ability for users to build an arbitrary tree of folders. Is there a way to do this?
I should have read one more paragraph here: https://guides.emberjs.com/v2.6.0/routing/defining-your-routes/
What I'm looking for is a wildcard / globbing route.
Router.map(function() {
this.route('folder', { path: '/f/*path' });
});
Gives me the output I was hoping for:
path=folder/subfolder
How can I handle the error
Uncaught Error: No route matched the URL '...'
and show a custom 404 page?
Note: This question was asked before and answered several months ago - but does not work anymore.
App.Router.map(function() {
//set up all of your known routes, and then...
this.route("fourOhFour", { path: "*path"});
});
.. where you have your FourOhFourRoute defined to show the "no route found" message of your choosing. You will be able to access the originally requested path in the fourOhFour route as the path parameter.
EDIT: just for clarity -- this answer came after the others were reported not to work anymore.
EDIT 2: I've updated the answer to reflect Yehuda Katz's comment (if I have it wrong, please LMK).
Here is an example:
I define the last route in my router using a wildcard route see: http://emberjs.com/guides/routing/defining-your-routes/#toc_wildcard-globbing-routes
I have a /not-found route, see last route defined in my router /*path to catch any text string, see: https://github.com/pixelhandler/blog/blob/master/client/app/router.js#L19
Router.map(function () {
this.route('about');
this.resource('posts', function () {
this.resource('post', { path: ':post_slug' });
});
this.resource('admin', function () {
this.route('create');
this.route('edit', { path: ':edit_id' });
});
this.route('not-found', { path: '/*path' });
});
That route does a redirect to /not-found, see: https://github.com/pixelhandler/blog/blob/master/client/app/routes/not-found.js
import Ember from 'ember';
export default Ember.Route.extend({
redirect: function () {
var url = this.router.location.formatURL('/not-found');
if (window.location.pathname !== url) {
this.transitionTo('/not-found');
}
}
});
Also any route having a hook (e.g. model, beforeModel, afterModel) that results in a rejected promise, can use the error action to transition to the 404.
actions: {
error: function (error) {
Ember.Logger.error(error);
this.transitionTo('/not-found');
}
}
Which renders a not-found template, see: https://github.com/pixelhandler/blog/blob/master/client/app/templates/not-found.hbs
<h1>404 Not Found</h1>
<p>
Perhaps you have a link that has changed, see {{#link-to 'posts'}}Archives{{/link-to}}.
</p>
Here is my 404 page: http://pixelhandler.com/not-found
You could try adding a catch-all route at the end of your router:
App.Router.map(function() {
this.resource('post', ...);
this.resource('user', ...);
this.route('catchAll', { path: '/*' });
});
App.CatchAllRoute = ...
In Ember 2.x
Inside the App.Router.map function, put code below the the end of the callback function.
this.route('your_handler_route_name', { path: '/*path' });
Now every route does NOT catche by the previous defined routes will be catched by your_handler_route_name route.
Solution 1
To display 404 content:
App.Router.reopen({
handleURL: function (url) {
try {
return this._super(url);
} catch (error) {
if (error.message.match(/No route matched the URL/)) {
return this._super('/404');
}
}
}
});
If you want to URL changes to 404 as well:
App.Router.reopen({
location: locationImplementation,
handleURL: function (url) {
try {
return this._super(url);
} catch (error) {
if (error.message.match(/No route matched the URL/)) {
this.transitionTo('404');
return this._super('/404');
}
}
}
});
To understand what happened here see line 22636 in ember rc2.
Solution 2
Parse current URL and check if route or resource exist using App.Router.router.recognizer.hasRoute('route.path.goes.here');
I have an application where I would like to namespace a specific route. But I'm seeing that Ember renders the ancestor route (which is similarly named).
Details
Ember 1.12.0
Routes
this.resource('campaign', { path: ':campaign_id' }, function() {
// some more routes
});
this.resource('campaign_v2', { path: 'v2/:campaign_id' }, function() {
// new routes
});
Link in campaign template
{{link-to "Check out V2!" "campaign_v2" classNames="btn btn-primary"}}
Test
Expect: When visiting campaign.index and I click on "Check out V2!", I expect to be taken to campaign_v2.index
Result: I am taken to campaign_v2.index but campaign also renders
Here is the result in Ember Inspector:
However, if I reload the route, I get:
Don't use the resource helper and instead use the route helper. Also, you might consider using a route namespace (instead of the _v2 suffix).
Routes
this.route('campaign', { path: ':campaign_id' }, function() {
// more routes
});
this.route('v2', function() {
this.route('campaign', { path: ':campaign_id' }, function() {
});
You can then refer to the v1 and v2 route via: campaign and v2.campaign respectively.