Ember.computed -- declaring additional dependencies (for example, Ember.computed.filter)


#1

When using the Ember.computed helpers, there are case in which it becomes necessary to declare additional dependencies. For example, when using Ember.computed.filter:

dogs: ...an array of dogs we load from somewhere...,
desiredColor: 'brown',
filteredDogs: Ember.computed.filter('dogs',function(item) {
    const wantedColor = this.get('desiredColor');
    return item.get('coat') === wantedColor;
})

This example works perfectly, including when I change the value of desiredColor… except that desiredColor cannot be declared as a dependency, so the filteredDogs property doesn’t recompute.

It is possible to make use of the old Ember 1.12 syntax to ‘fix’ this – for example:

dogs: ...an array of dogs we load from somewhere...,
desiredColor: 'brown',
filteredDogs: Ember.computed.filter('dogs',function(item) {
    const wantedColor = this.get('desiredColor');
    return item.get('coat') === wantedColor;
}).property('dogs.@each.coat','desiredColor')

but this seems like a bad idea, since I’m guessing the .property method will be removed at some point.

Is there any “proper” way to do this? Does the Ember team have any opinion on how this should be accomplished? Or is it necessary to write your own computed property for each such case?

Thanks in advance!


#2

We use ember-cli-filter-by-query like this:

import computedFilterByQuery from 'ember-cli-filter-by-query/util/filter';

  filteredContent: Ember.computed('arrangedContent.@each.number', 'arrangedContent.@each.client','arrangedContent.@each.description', 'filterQuery', function() {
    return computedFilterByQuery(
      this.get('arrangedContent'), ['number', 'client.name', 'description'], this.get('filterQuery'), { conjunction: 'and', sort: false }
    );
  }),

#3

I know that it is not what you asked, but you can just do it like

filteredDogs: Ember.computed('dogs.@each.coat', 'desiredColor', function () {
  let wantedColor = this.get('desiredColor');
  return this.get('dogs').filter((dog) => dog.get('coat') === wantedColor);
})

#4

Very true, but that does someone obviate the purpose of Ember.computed.filter :slight_smile:


#5

It seems like this usecase should be supported by computed.filter. In the mean time, define a factory function which builds the pattern @mupkoo presented. You’ll have your own, better version of computed.filter. I usually end up with a few different computed property factories in my projects, to cover common patterns specific to the application