Ember.js: Reloading a .hasMany relationship given through "links" in payload

Javascriptember.jsEmber Data

Javascript Problem Overview


Say I have two models, Topic and Post:

App.Topic = DS.Model.extend({
  posts: DS.hasMany('post', { async: true, inverse: 'post' });
});

App.Post = DS.Model.extend({
  topic: DS.belongsTo('topic', { async: true });
});

Topic hasMany Posts, and a Post belongsTo a Topic.

To load the data from the API, one initial call is made (which fetches a topic... topic ID 2 for example): GET /topics/2

After receiving the payload for this GET request, the serializer then appends a links key to the payload. This has the route to load the Posts associated with the topic:

"topic": {
   "id": 2,
   "links": {
      "posts": "/topics/2/posts"
   }
}

This second request (to /topics/2/posts) is how the Posts are loaded and attached to the topic.

This all works fine when the page is first loaded.

The problem occurs when a Post is created during a page session. While I can get the topic itself to reload (by calling .reload() on the model object that represents the topic), the Posts associated with the topic are not reloaded. The second API call (to get the posts) is never even made, while the first call (to get just the topic) is made. If I refresh the page, the posts I created on the previous page load will load (but of course, if I then go and make some more posts, they won't show up until the next page load).

Looking for a solution, I came across this question: https://stackoverflow.com/questions/19983483/how-to-reload-an-async-with-links-hasmany-relationship

However, it appears that the solution no longer works for the current versions of Ember/Ember-Data. The JSFiddle provided does not function.

So, how can I reload this sort of hasMany relationship? Any help is greatly appreciated.

Javascript Solutions


Solution 1 - Javascript

DS.Model.reopen({
  reloadLink: function (linkKey) {
    if ($.isArray(linkKey)) {
      var promises = [];
      for (var i = 0; i < linkKey.length; i++) {
        promises.push(this.reloadLink(linkKey[i]));
      }
      return Em.RSVP.all(promises);
    } else {
      var rel = this._relationships[linkKey];
      if (rel) {
        if (rel.reload) {
          return rel.reload();
        } else if (rel.fetchLink) {
          return rel.fetchLink();
        }
      }
    }
  }
});

Example:

model: function () {
    var model = this.modelFor('_some_model_');
    return model.reloadLink(['link1', 'link2']).then(function () {
      return model;
    });
}

Solution 2 - Javascript

So there is an issue on GitHub that is not closed yet (As of today): https://github.com/emberjs/data/issues/1913

I do not know how to make it reload, but I thought that I will share the workaround that I did to resolve this issue.

I am using websockets, so when ever a new post is being created, I just send it through websocket and use the data to update the collection.

I am aware that this does not fix the issue with Ember Reload, but I guess this is a decent solution to the people who are already using Websockets / Socket.io.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMikeView Question on Stackoverflow
Solution 1 - JavascriptOlegDovgerView Answer on Stackoverflow
Solution 2 - JavascriptdhilipsivaView Answer on Stackoverflow