Question

Hopefully you can help me!

My Ember App (Ember 1.5.1) has two models (Ember Data beta7): Item and Tag. Item hasMany Tags.

I also have a computed property on tags which doesn't update. The computed property is a simple check to see if there are any tags (ie not empty). I've tried various things. I got as far as arrayComputed and then stopped. It should be reasonably trivial to check if an async related model has a count higher than 0! I've tried "tags.[]", "tags.@each", "tags.@each.status", "tags.@each.isLoaded", "tags.length" and various other things.

The computed property on the belongsTo works fine.

App.Item = DS.Model.extend({
  tags: DS.hasMany("tag", inverse: "item", async: true),
  hasTags: function() {
    return !Em.isEmpty(this.get("tags"));
  }.property("tags")
});

App.Tag = DS.Model.extend(
  item: DS.belongsTo("item", inverse: "tags"),
  hasItem: function() {
    return !Em.isEmpty(this.get('))
  }.property("item")
);

If I change it to read like this, then the log gets a line printed in it, so the promise is actually fulfilling and loading. I just don't know what to put on the computed property to make it reload when the promise has fulfilled. I feel like I'm missing something super obvious:

App.Item = DS.Model.extend({
  tags: DS.hasMany("tag", inverse: "item", async: true),
  hasTags: function() {
    this.get("tags").then(function(tags) {
      console.log("The tags are loding if this is printed");
    });
    return !Em.isEmpty(this.get("tags"));
  }.property("tags")
});

[ edit ] 7 May 2014

Okay so I didn't fully explain the question properly the first go around I guess because I didn't fully understand what was wrong... I've continued the quesiton in the following stack overflow issue: Route's Model Hook with Ember Data "filter" not loading dependent computed property

Was it helpful?

Solution

I believe what you are looking for is this:

App.Item = DS.Model.extend({
  tags: DS.hasMany("tag", inverse: "item", async: true),
  hasTags: function() {
    this.get("tags").then(function(tags) {
      console.log("The tags are loding if this is printed");
    });
    return !Em.isEmpty(this.get("tags"));
  }.property("tags.@each")
});

Because tags is an array, you want to be notified when tags are added or removed. the '.@each' will make it update when this happens.

OTHER TIPS

Okay hopefully someone has a better answer than this, but this is how I've "gotten around it" for now, in my routes (I feel like this is an absolutely ridiculous way to do it), by adjusting the thing that relies on "hasTags" rather than adjusting hasTags itself.

Note I'm not even sure if I "fixed up" "hasTags" in Item whether or not it would trigger the filtered reference below to update...?

I think perhaps we need filter to be promise-aware in its block (ie so you can use properties to filter that are promises and it'll do the right thing):

App.TaggedItemsListRoute = App.ItemsRoute.extend({
  model: function() {
    var store = this.get("store");
    var storePromise = store.find("item", { has_tags: true });
    var filtered = store.filter("item", function(item) {
      var tags = item.get("tags");
      if tags.get("isFulfilled") {
        return item.get("hasTags");
      } else {
        return tags.then(function() {
          return item.get("hasTags");
        });
      }
    });
    return storePromise.then(function(response) {
      return filtered;
    });
  }
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top