Howto get hasMany data loaded in a nested route from a custom API server


#1

Hello guys,

I’am struggling to find the best practice solution, for my situation, to load hasMany records from an custom REST API server.

Below I have listed my situation including three attempts(see solution[1,2,3]). I hope you guys can guide me in this.

My situation:

I am displaying a ‘post record’ in post.hbs and trying to display multiple ‘comment records’ in comments.hbs on a single page, via a nested route(/posts/{post_id}/comments.

Models

Post.js

export default DS.Model.extend({
  comments: DS.hasMany('comment'),
  messsage: DS.attr()
});

Comment.js

export default DS.Model.extend({
  post: DS.belongsTo('post'),
  date: DS.attr()
});

Nested route

/posts/{post_id}/comments

Router.js

...
  this.route('posts/edit', { path: '/posts/:post_id' }, function() {
    this.route('comments', function() {
      this.route('new');
      this.route('edit', { path: ':comment_id' });
    });
...

REST Server API

GET /posts/{id}
{
 "id" : "1",
 "message" : "hello"
}
GET /comments?post={post_id}
[{
 "id" : "324",
  "date" : "01012015"
},
{
 "id" : "24",
  "date" : "02012015"
}]

Solution one

/routes/posts/edit.js

model(params) {
  return this.store.findRecord('post', params: post_id );
}

/routes/posts/edit/comments.js

model() {
  let post=this.modelFor('posts/edit');
  return this.store.query('comment', { post: post.id });
}

This solution is working, but new added comments(using the route /posts/{id}/comments/new) are only visible after a reload of the page.

Solution two

/routes/posts/edit.js

model(params) {
  return this.store.findRecord('post', params: post_id );
}

/routes/posts/edit/comments.js

model() {
  let post=this.modelFor('posts/edit');
  let comments=this.store.query('comment', { post: post.id });
  post.set('comments',comments);
  return post.get('comments');
}

This solution is working, but when the user navigates away and back through ‘link-to’ helpers the ‘comments’ are not shown, while they are still loaded in the store…

Solution three

/routes/posts/edit.js

model(params) {
  return this.store.findRecord('post', params: post_id );
}

/routes/posts/edit/comments.js

model() {
  let post=this.modelFor('posts/edit');
  return post.get('comments');
}

/serializers/post.js

normalizeResponse(store, primaryModelClass, payload, id, requestType) {
....
  commentLink='/comments?post='+post_id
  result.links={ 'comments' : commentLink };
...
}

This solution works perfectly, but I am unsure if “adding links to the records at the REST serializer” is the right thing to do.


#2

Hi Rick, solution three is the right way to handle it!


#3

Hi Frank,

Thanks for you reply.

I will implement solution three.

Cheers!