Arbitrary depth slash-delimited param value in Ember route - ember.js

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

Related

What is the difference between route and path in EmberJs

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

Is it possible to make a parent route a 404, but the child route a specific route

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.

Add a parent route in ember for existing routes

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 :)

Ember nested global routes (Wildcard)

I'm trying to do something like this in my routes:
this.route('products', { path: "/products/*choises"}, function() {
this.route('promotion', {path: "/promotion/*offers"});
});
product route:
offerPath: function(params){
this.transitionTo('product.promotion', params);
}
The problem is that it doesn't matter the promotion that I visit, the app thinks is part of the products route.
How can I do this? I need them to be nested.
Update:
You can use beforeModel(transition) hook in router to check what's in the url.
http://example.com/products/manufacturer-209/series-881/tag-17143/none/494822/f‌​lawless
import Ember from 'ember';
export default Ember.Route.extend({
beforeModel(transition) {
console.log(transition.params.products.choises)
// if you use this url: http://example.com/products/manufacturer-209/series-881/tag-17143/none/494822/f‌​lawless
// console log would be: "manufacturer-209/series-881/tag-17143/none/494822/f‌​lawless"
}
});
At least you have the rest of the url so, you can filter out the important information and redirect with this.transitionTo() to the exact place.
You could have the following route:
http://example.com/products/123/promotions/456
or
http://example.com/products/awesome_souce/promotions/monday_deal
In the first case, your route would look like this:
this.route('product', { path: "/products/:product_id"}, function() {
this.route('promotion', {path: "/promotions/:promotion_id"});
});
In the second case, maybe like this:
this.route('product', { path: "/products/:product_name"}, function() {
this.route('promotion', {path: "/promotions/:promotion_name"});
});
Finally, your route handlers can download the proper models (example for the first case):
// app/routes/product.js
import Ember from 'ember';
export default Ember.Route.extend({
model(params) {
return this.store.findRecord('product', params.product_id);
}
});
---
// app/routes/product/promotion.js
import Ember from 'ember';
export default Ember.Route.extend({
model(params) {
// you can get access to the parent route model if you need for the api query
const product = this.modelFor('product');
return this.store.findRecord('promotion', params.promotion_id);
}
});
If you need only the param from the product route, instead of returning a whole record, for example you can just return params.product_name, so you will have access to a string with this.modelFor('product') in a subroute level.

Ember Router rootURL option (Uncaught Error: No route matched the URL '/admin')

I'm trying to start to build a admin system that will run on a /admin/ prefix.
Here is my routes file
App.Router.reopen
location: 'history'
rootURL: '/admin'
App.IndexRoute = Ember.Route.extend
setupController: (controller, model) ->
#controllerFor('application').set('currentRoute', 'home')
When I go to /admin I get the following error:
Uncaught Error: No route matched the URL '/admin'
I'm just starting with emberjs, and my code is based on this serie
Ember version: v1.0.0-pre.4
Ember-data current api revision:: 11
In old-router the 'rootURL' property would have been ignored when resolving routes. In the latest version of ember, rootURL only seems to be used when constructing links. Not sure if this is a bug or oversight. As a workaround, try this instead:
App.Router.map(function() {
this.resource("admin", { path: "/admin" }, function() {
this.route("other");
});
});
App.IndexRoute = Ember.Route.extend({
redirect: function() {
this.transitionTo('admin');
}
});
When talking about routing in emberjs, it depends which version you are using. There was a big API change between 1.0pre2 and 1.0pre3. The docu on www.emberjs.com is already up-to-date for the new API and and easy to understand.
Below a really small example that shows
IndexRoute that automatically redirects to the overview of all members at '/members'.
Dynamic routing based on an ID
Serialization/Deserialization in case that the parameter is not 'id' but something else. In the example below, it is 'refId' (stands for reference ID).
Well, the examle does not really show more than the official documentation. but add-on information is always nice.
So, hope this helps. cheers.
App.Router.map(function() {
this.resource("members", { path: '/members' });
this.resource("member", { path: "/members/:refId" }, function() {
this.route("delete");
});
});
App.IndexRoute = Ember.Route.extend({
redirect: function() {
this.transitionTo('members');
}
});
App.MembersRoute = Ember.Route.extend({
model: function() {
return App.Member.findAll();
}
});
App.MemberRoute = Ember.Route.extend({
model: function(params) {
return App.Member.find(params.refId);
},
// overwrite default serializer (defaults to 'id', member has 'refId')
serialize: function(model) {
return { refId: model.refId };
}
});