How can I look into the content of a hasMany relationship?

I have a model Node

:

App.Node = DS.Model.extend({
    parents: DS.hasMany('node', { inverse: null })
});

      

Let's say my server sends a partial tree:

{ id: "A", parents: [ "C" ] }
{ id: "B", parents: [ "C", "D" ] }
{ id: "C", parents: [ "E" ] }

      

I want to do it like this:

A ---- C
      /
B ---/

      

However, when I call B.get('parents')

, I get a message that says:

Failed to get error: Assertion failed: you looked at the parent relationship on node ID B, but some related records were not loaded. Either make sure they are all loaded along with the parent entry, or specify that the relation is async ( DS.hasMany({ async: true })

)

I don't need any of them. I only want the loaded entries in the chart.

Ultimately I will want to do something like this:

A ---- C--?
      /
B ---/--?

      

Representing nonessential parents with a UI element.

Is there a way to view only uploaded records in a relationship?

+3


source to share


3 answers


Great question.

Currently Ember data is not suitable for such use cases.

Your question was answered , but is now deprecated: the API has changed and it is now closed.

If you are brave enough, you can do something like this:

App.Node = DS.Model.extend({
  parent:   DS.belongsTo('node', {inverse: 'children'}),
  children: DS.hasMany('node', {inverse: 'parent'}),

  childrenIds: Ember.computed(
    '_internalModel._relationships.initializedRelationships.children.canonicalState.@each.ids',
    function() {
      var children =
        this
          ._internalModel
          ._relationships
          .initializedRelationships
          .children;

      if (!children) return [];

      return children
        .canonicalState
        .mapBy('id');
    }
  ),

  availableChildren: Ember.computed('childrenIds', function () {
    var childrenIds = this.get('childrenIds');
    return this.store.all('node').filter(function(node) {
      return childrenIds.indexOf(node.id) > -1;
    });
  })
});

      

Demo: http://emberjs.jsbin.com/qugofu/1/edit?html,js,output

The problem with this code (other than using the private API) is that the property availableChildren

will not automatically update when new nodes are received from the server.



You will need to figure out how to do this. When you do, release it as an addon!

UPD 2015-07-20

This question kept me awake.

I was able to improve the above solution:

  • It now updates automatically when new records appear in the repository.
  • It is also updated when record relationships change.

The disadvantage is that the search for available nodes occurs in the component and not in the model.

Demo: http://emberjs.jsbin.com/qugofu/2/edit?html,js,output

+3


source


As the other answer rightly says, Ember Data has a hard time dealing with this. A related situation is trying to find the length (count) of an async relationship hasMany

without involving network requests. The problem is that a property parents

is essentially a promising array, which should be a promise for something .

If you don't want to work in Ember Data internally, I would handle this problem by ditching hasMany

and just defining the field as an array of IDs. Then, when you really need the parent objects, do find

to get them. You can use coalesceFindRequests

in adapter to ensure that Ember only makes one network call to get both parents (if your server can handle the format api/nodes?ids[]=A&ids[]=B

).



If you are so inclined, you can encapsulate this behavior in mixins on serializers and models.

+2


source


Currently (2016-07-03) this can be accomplished using method : DS.Model

hasMany()

var children = model.hasMany('children').value();

      

+1


source







All Articles