0
votes

I have a nested route setup as I would like to have my templates nested as well. The route setup looks like this:

...

      this.route('posts', function() {
        this.route('post', {path: ':post_id'}, function() {
          this.route('comments',  {path: 'comments'}, function() {
            this.route('comment',  {path: ':comment_id'});
          });
        });
      });

...

Potentially, my URL could look something like this: /posts/:post_id/comments/:comment_id

If I navigate via {{link-to}} then I have no problem, however, if I go directly to a specific URL via the browser, that's when things going wrong. Imagine that my comments page lists the comments associated with the post (post_id) I'm looking at. The problem is going there directly, like typing in /posts/123/comments/56 doesn't load the list of comments, only the comment itself. Here is how my routes are setup:

// routes/posts.js
...
model() {
    return this.get('store').findAll('post');
}
...

// routes/posts/post.js
...
model(params) {
    return this.get('store').findRecord('post', params.post_id);
}
...

// routes/posts/post/comments.js
...
model(params) {
    let post=this.modelFor('posts/post');
    return post.get('comments');

}
...

// routes/posts/post/comments/comment.js
...
model(params) {


    return this.store.findRecord('comment', params.comment_id);

}
...

If I type in /posts/123/comments/56, no list is displayed from the comments.js template.

If I type in /posts/123/comments, only the first comment is displayed from the comments.js.

I'm not sure what I'm doing wrong though I feel like it has something to do with modelFor. How do I properly populate/hydrate the post's comments list when I go directly to a comment in that post URL rather than navigating there via link-to?

UPDATE 1: Here are the models:

// post.js
export default DS.Model.extend({
    title: DS.attr("string"),
    articles: DS.hasMany('comment', {async: true})
});
// comment.js
export default DS.Model.extend({
    title: DS.attr("string")
});

I've connected it to mirage.

Here is a sample of the comments fixture:

[
    {
        id: 1,
        title: "Apple"
    },
...

and the posts fixture:

[
    {
        id: 1,
        title: "A post with fruits for comments",
        commentIds: [1, 2]
    },
...

UPDATE 2:

I've added my template code for templates/posts/post/comments.js

Comments.js!
{{outlet}}
<ol>
    {{#each model as |comment|}}
        <li>{{#link-to "posts.post.comments.comment" comment}} {{comment.title}}{{/link-to}}</li>
    {{/each}}
</ol>

I've also updated the comment.js route above, reducing its complexity.

1
Can you show us what your models look like and the JSON that back those modelskiwiupover
I updated the post with some more info. The data is there and works without the URL, it's just the nested routes break down when you try to access it directly.Jason
this.modelFor('posts/post') is it returning post model and is that working for you? i thought it would be this.modelFor('posts.post'). anyway correct me if yours working.Ember Freak
I've tried both with / and . with the same results.Jason

1 Answers

0
votes

Based on your router definitions - the URL /post/123/comments/56 does not exists. Your router defines URL with the following structure /posts/56/comment/123 (notice singular comment not comments) - your route name is comments however you told ember that the path it should resolve is comment - singular. So, try accessing /post/123/comment/56 instead of comments. Also, no reason to call this.modelFor('posts/post') from nested comments route - all you should need is modeFor('post'). And the last thing, inside the comment route you should only need to look for a give comment no need to resolve the parent model - you already have a unique comment_id - store.findRecord('comment', comment_id) should work.