Reputation: 3260
i'm learning Ember.js but i'm struggling to figure out why my routes aren't working properly.
Here are the relevant parts of my app.js:
// Routes
App.Router.map(function() {
this.resource('posts', { path: '/posts' });
this.resource('post', { path: '/post/:id' });
});
// Handle route for posts list
App.PostsRoute = Ember.Route.extend({
model: function() {
return App.Post.findAll();
}
});
// Handle route for single post
App.PostRoute = Ember.Route.extend({
model: function(params){
return App.Post.findById(params.id);
}
});
// Post model
App.Post = Ember.Object.extend();
App.Post.reopenClass({
findAll: function(){
var posts = [];
$.getJSON("/api/posts").then(function(response){
response.posts.forEach(function(post){
posts.pushObject(App.Post.create(post));
});
});
return posts;
},
findById: function(id){
$.getJSON("/api/post/" + id).then(function(response){
return App.Post.create(response.post);
});
}
});
Then in my template I have this:
<!-- Post list -->
<script type="text/x-handlebars" data-template-name="posts">
<div class="large-12 columns">
<h1>Posts</h1>
<hr>
<ul>
{{#each post in model}}
<li>{{#linkTo 'post' post}}{{post.title}}{{/linkTo}}</li>
{{/each}}
</ul>
</div>
</script>
<!-- Single post -->
<script type="text/x-handlebars" data-template-name="post">
<div class="large-12 columns">
<h1>{{title}}</h1>
<div class="content">
{{post_content}}
</div>
</div>
</script>
I'm having a few issues here. Firstly, the href attribute on the links in the post list are coming out like this:
#/post/<App.Post:ember217>
I can fix this by changing my post route to:
this.resource('post', { path: '/post/:post_id' });
But then when I try to navigate directly to a post by using a URL like /#/post/1
I get an error:
Assertion failed: Cannot call get with 'id' on an undefined object.
Finally, if I leave my post route how it is (/post/:id
) then visit the URL /#/post/1
none of the post data is displayed. I can see the correct API endpoint is called and no errors are shown in the console.
However, if i click through to the single post from the posts list the post is displayed properly but it uses the weird URL that I mentioned earlier - #/post/<App.Post:ember217>
.
If this helps, this is the JSON the post models are created from:
{"post":
{
"id":2,
"title":"Second post",
"alias":"second-post",
"postedOn":"2013-08-12 09:11:37",
"authorId":1,
"post_content":"Post content"
}
}
Sorry i know there's quite a bit there - I hope it's enough to give a clear picture of what I'm doing wrong.
Thank you
Upvotes: 0
Views: 545
Reputation: 19128
You are receiving this url #/post/<App.Post:ember217>
because your dynamic segment is /post/:id
, you have to change to yourmodel_id
, in your case is /post/:post_id
. Using this, by default the route serialize
method will know that you want the id
atribute of the post
, in the url: /post/1, /post/2 etc. And no override will be needed in that case.
You have said that changing to post_id make the url generation works, but the navigation no, when navigate to url directly, but the problem isn't the routing, I think that is because you are using:
App.Post.findById(params.id);
You have to update to:
App.Post.findById(params.post_id);
Other problem that I see (don't know if is a typo mistake), you forget the return
in ajax call:
findById: function(id){
// you must return the ajax
return $.getJSON("/api/post/" + id).then(function(response){
return App.Post.create(response.post);
});
}
I hope it helps.
Upvotes: 1
Reputation: 47367
Ember likes your objects to have an id property for generating the url. If you are going to use something other than id in the route (such as :post_id) you'll need tell Ember how to deserialize your model for generating the url.
App.PostRoute = Ember.Route.extend({
model: function(params){
return App.Post.findById(params.id);
},
serialize: function(model) {
return { id: model.get('id') };
}
});
App.PostRoute = Ember.Route.extend({
model: function(params){
return App.Post.findById(params.id);
},
serialize: function(model) {
return { post_id: model.get('post_id') };
}
});
Upvotes: 0