Ember.js: Reloading a .hasMany relationship given through "links" in payload
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: 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.
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;
});
}
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.