Ember js, Ember data: filtering in Controller not resolving the belongsTo relationship whereas template does


#1

The full list of inspections is provided by the Route and stored in fixtures. I’m trying to extract the current inspections from the full inspection list using a computed property with a filter from within the controller…

When I display the elements from the model in the template and access the item.status.code, it is resolved properly.

When I try to filter on that property from the controller, it seems it is not available (loaded:= false - see the logs in the browser console when running the JSBin Demo of the problem).

App.IndexController = Ember.ArrayController.extend({
  currentInspections: function() {
  var mod = this.get('model');
  Ember.Logger.log('Model: ', mod);
  return mod.filter(function(item, index, enumerable) {
    Ember.Logger.log("Inspection:            ", item);
    Ember.Logger.log("status --> isLoaded:   ", item.get('status').get('isLoaded'));
    Ember.Logger.log("status --> unique get: ", item.get('status.code'));
    Ember.Logger.log("status --> 2 get:      ", item.get('status').get('code'));
  
    return item.get('status.code') === "inProgress";
  }); 
}.property("model.@each")

Yields the following:

Model:  
Class {type: function, store: Class, isLoaded: true, isUpdating: false, toString: function…}
Inspection:             
Class {id: "1", store: Class, container: Container, _changesToSync: Object, _deferredTriggers: Array[0]…}
status --> isLoaded:    false
status --> unique get:  undefined
status --> 2 get:       undefined
...

Either I’m missing the way it is supposed to be done or there might be a bug in ember-data or emberjs itself that makes the object not loaded at this stage in the event processing chain…

I’ve been fiddling with this for a while now and I’m going round and round in circles not finding the solution…

Could someone inspired have a look at it, I really need an external view on this problem.

Is there a way to force the load of the status object?

Should I be doing this filtering somewhere else?

NB: this question is also on Stack overflow


#2

I had a hard time figuring this out, but it appears that even though you’re using the fixture adapter, the status records are not immediately available during the filter function, as indicated by isLoaded===false. They become available shortly after. My guess is that the currentInspections property is resolved before the associated status records are loaded (because this property is required by the template), and then doesn’t recompute. I’ll keep thinking on it.

In the meantime, you can use this property definition, which works for me:

currentInspections: Ember.computed.filterBy('model', 'status.code', 'inProgress'),

#3

If you’re using the FixtureAdapter, maybe simulateLatency can help if that’s not already setup.


#4

Fantastic ! It works a treat !

I’m just wondering why the currentInspections property gets resolved like it does and is not ‘refreshed’… ‘auto-magically’.

Do you think maybe the currentInspections: function() {}.property(…) or Ember.Computed(function() {}) are missing an event hook??

If I find the time I might actually go debug it out in the ember code :wink:

Thanks for your solution.