Loading relationship data of a model from secondary API request without recreating objects if already exist

Im trying to load comment list which may haves children comments as well. Comment model may have reference for parent comment or its children comment list if any. As the requirement I should load all comments (parent and children) from multiple comment threads into single list using first API call. In that stage there is only comments list but no any parent child relationship between comments. If user click on comment respective comment thread should be loaded. For that parent and children request are send from the model, those secondary api calls will retrieve the relevant parent or children data.

export default CommentModel.extend(ModelLikeableMixin, {
  parent: computed(function() {
    return get(this, 'store').queryRecord('comment', {
      _overrideURL: `comments/${get(this, 'id')}/parent`,
    });
  }),

  children: computed(function() {
    return get(this, 'store').query('comment', {
      _overrideURL: `comments/${get(this, 'id')}/children`,
    });
  }),
...

The issue is when retrieving child comments data from secondary request, that caused to reload already existing comments object again, and comment components of the comment list.

I want to know is there any way in the ember data to update links of model relationships if required object are already exists in the store, without recreating/reloading same object.

Here is my Stackoverflow issue.

That’s one of the issues with using links-based relationships instead of id based relationships. Since the relationship “link” is the source of truth about what records are in that relationship it becomes an all-or-nothing sort of deal. You could also consider using actual ember data relationships instead of computed properties here, but I don’t think that will really work any differently at the end of the day.

If you’re concerned about re-rendering rather than refetching you could probably figure out a way to optimize the rendering (like using the key arg with your each helper) so it doesn’t rerender comments that it already has

1 Like

Hi @dknutsen, Thanks for the reply. I tried the your suggestion which is using key arg with the each helper. But comments components are getting unloaded when receiving child data response. Is there any event from ember model before creating objects from the response. If there is any, I can check manually if it already exist and return existing one.

This is difficult to debug without seeing more of your code, but I’d also recommend using Ember Data relationships (with links) instead of computed properties for fetching the relationships. Those references will be more “stable” and have a better API for refreshing, etc. so it may fix your problem and would also be a little more ergonomic.

There are probably a couple ways you could do that but the most straightforward might be converting your computed properties above to a belongsTo and hasMany relationship respectively, and then adding a links relationship in your comment serializer. This code probably doesn’t work but something along these lines:

  normalize(model, hash, prop) {
    const superHash = return this._super(...arguments);
    superHash.links = superHash.links || {};
    superHash.links.children = `/comments/${hash.id}/children`;
    superHash.links.parent = `/comments/${hash.id}/parent`;
    return superHash;
  }

this simply tells ember data that each model has a links relationship URL as if that came from the API.

Once you have that set up you can fetch the relationships with the Ember Data relationship API which will probably behave better.