Using Ember 2.1.0 with EmberData, I'm making a small blogging app. It has two routes
Router.map(function(){
this.route("posts", {path: "/"});
this.route("post", {path: '/:seo_friendly_link'});
}
The seo_friendly_link looks like this
/2015/10/28/my-blog-post-title/
In the index route, I display a list of posts with links to each post. If I click a link, the Ember app will transition to the post that I clicked on showing the seo-friendly-url in the browser. I emphasize transitionto-- the routing goes through that method in Ember router. Everything works fine up to here.
The problem:
However, if I drop/type that same url into the browser (rather than transition to it from a link on the homepage), I get an UnrecognizedURLError (before the model or even the beforeModel hook are called for the post). If I drop the url into the browser, the routing goes through the handleURL method on Ember Router, which doesn't happen if I click a link from the homepage. So my Ember app can transition to my seo_friendly_link, but not handle that url.
I'm not sure why.
Question: How can I create a route to recognize that link?
Code
There is a property on the Post model called
seo_friendly_link: DS.attr('string')
In /routes/post, I call the serialize method to create that parameter from the model property
serialize: function(model, params){
seo_friendly_link: model.get("seo_friendly_link");
}
Your dynamic segment /:seo_friendly_link doesn't match slashes, e.g. it will match /2015 but not /2015/10.
To match the whole path including slashes, change the : to an *:
Router.map(function(){
this.route("posts", {path: "/"});
this.route("post", {path: '/*seo_friendly_link'});
}
Related
I want to add the component's name to the URL in Ember js.
Example:
If the main URL is : localhost:4200/home ,
then in home,if I call/redirect to a component(say - abc), the URL should get appended:
localhost:4200/abc
or
localhost:4200/home/abc
If the main URL is : localhost:4200/home , then in home,if I
call/redirect to a component(say - abc), the URL should get appended:
How do you call/redirect to a component in ember?. If you got some hacky way to do that, then I will encourage you not to do this.
In Ember, the router matches the current URL to the routes that you've defined.
If you got /home/abc URL path, it means you have abc route nested inside home route.
Router.map(function() {
this.route('home', function() {
this.route('abc');
});
});
If you know all routes will come under home route, then you can define it manually. Suppose if you don't know or what will come , then go for defining the dynamic segments in URL.
You can do it by {{component}} helper.
You need to define dynamic path for home and send the component name from url to home controller by model hook.
Below are essential parts of the solution.
//router.js
this.route('home', {path: 'home/:cmp'});
//routes/home.js
model(params){
return params.cmp;
}
//templates/home.hbs
{{component model}}
Please take a look at this tiwddle
I have the router.js file of my project set up as follows:
Router.map(function() {
this.route('login');
this.route('projects', {path: '/'});
});
Whenever I visit the /login page, no content is displayed. Also, the following error appears in the console:
Error: There is no route named index
However, whenever I remove {path: '/'} from route, the login page works without issue.
Why is this happening? I've noticed that in other Ember projects like Ghost are able to achieve this just fine without any conflicts with a non-existent index route.
Note: I am using an ember-simple-auth mixin to redirect the visitor from / to /login.
I ran into the exact same problem when I tried to add the following route to my application:
this.route('user', { path: '/' });
I determined the problem was that in one of my templates I had a link like:
{{#link-to "index"}}Home{{/link-to}}
Since the root (index) path now belongs to the user route, there is no index rout. I needed to update my link to:
{{#link-to "user"}}Home{{/link-to}}
I suspect you might be referencing the index route, which no longer exists, somewhere in your templates or other code. Changing that to "projects" should work for you.
I have in my Ember app this routes:
Router.map(function() {
// landing page (login/register)
this.route('home', {path: '/'});
// authenticated pages
this.route('webappFrame', {path: '/app'}, function() {
this.route('feed', {path: 'feed'});
this.route('photoDetail', {path: 'photo/detail/:id'});
});
});
where both "feed" and "photoDetail" have a model hook that return a promise (records coming from the server);
I have a loading.hbs template in the /template folder;
After a page refresh on both "feed" and "photoDetail" routes, the loading template is correctly displayed;
but when navigating between the routes, it is not shown again (the outlet remains white untile the promise is resolved);
I use ember-cli 2.3.0-beta.1 (but also tried 1.13.14 stable) with ember 2.3.0;
In the official ember docs is written that it should always traverse the templates tree up until it finds a loading template;
can someone show me what's wrong here?
UPDATE ----------------------------------------------------
// feed model hook
model: function(params, transition) {
return this.store.query('photo', {type: 'feed'});
}
// photoDetail model hook
model: function(params, transition) {
var self = this;
return Ember.RSVP.hash({
photo: self.store.find('photo', params.id),
comments: self.store.query('comment', {id: params.id})
});
},
and in feed template:
{{#each photo as |item|}}
{{photo-item item=item}}
{{/each}}
and then the photo-item component:
{{#link-to "webappFrame.photoDetail" item.id}}
<img class="photoImage" src="{{imageurl item.hash type='photo'}}">
{{/link-to}}
where {{imageurl}} is just an helper that creates the path for the image;
here i pass "item.id" to the link-to (instad of passing "item" itself) to force the reload of the photo when entering detail (in order to get also comments)
right now, I've added templates/webapp-frame/loading.hbs and it works;
the thing is that the loading template is always the same in the whole app; so I expected to have only one instead of having a copy of it in every /templates subfolder...
Ember handles the loading templates per route, its always "routename-loading.hbs", it seems you have not created the matching templates that´s why you only see a white page (default). If you´re not sure which templates are necessary or how they have to be named, install ember inspector and check the routes tab, there you can see what ember expects and how it should be named.
I have this on my router.js:
this.resource('campaigns', {path:'/campaigns'}, function() {
this.route('index', {path: '/'});
this.route('group', {path: '/*campaign_group_id'});
});
So it's a route called campaigns, and 2 nested routes: index and group.
When the browser is on the group route, I need to access the model from group route, on the campaigns route/controller.
But I can't access it. I always get the model that it's on campaigns.js route.
If you set the model from the campaign.group route on its controller, you should be able to use controllerFor to from the campaigns route, something like
// routes/campaigns.js
this.controllerFor('campaigns.group').get('your-prop')
You could also send an action from your group route and handle it in the parent campaigns route, sending along the model. This is perhaps more idiomatic with Ember 2.0 conventions.
Btw if you're using Ember CLI (which you should be) you should try getting rid of this.resource and putting all your routes/templates/controllers in pods.
Here are my routes:
this.resource('kb_obj', {path: '/kb/:data_type'}, function() {
this.resource('kb_obj_show', {path: '/:id'}, function() {
this.route('with_breadcrumb', {path: '/:breadcrumb'});
});
this.resource('kb_filtered_page', {path: '/:filter_params/page/:page_id'}, function() {
this.route('index', {path: '/'});
});
});
As you can see, the KbObjRoute's main job is to store the current data type.
My problem is that when someone clicks a link such as this:
{{#linkTo 'kb_obj_show.with_breadcrumb' this this}}{{name}}{{/linkTo}}
The model or setupController methods are not fired on the KbObjRoute, so it never gets to update its data type and anything that depends on that info (e.g. the main nav links) don't get updated.
I can't see how to notify the parent route of what's going on with its children.
Am I missing something?
Thanks!
I think there might be two misconceptions here
your sub-routes build on the parent route but don't modify it (more
below) perhaps there is a mismatch with what you are trying to achieve
and the URL structure
the model method won't be called for a linkTo (because the
linkTo is supplying the model). if someone drops directly into the
route they will be called
The URL /kb/image might load a bunch of images as the model. /kb/image/123 is one of those images. Changing 123's data_type isn't going to bubble up and change the dynamic segment.
That being said, routes and controllers can depend on eachother in a few ways.
With routes, you can use the modelFor method, in your case I think it would be:
this.modelFor('kb_obj')
With controllers you would use the needs array. So if you wanted to get a model or property from another controller you can do that:
App.SubController = Ember.ObjectController.extend({
needs: "otherController",
linkedProperty: Ember.computed.alias("controllers.otherController.model.itsProperty")
});