tarponjargon
tarponjargon

Reputation: 1032

Ember: computed property (object) not updating in view

I'm new to ember and am creating a search filtering app. I have my search filter "buckets" set up as controller properties and they are bound nicely to query parameters.

I'm looking to create a "your selected filters" component that summarizes what filters the user has currently active. I'm thinking maybe a computed property is the way to do this? In my controller I created one called selectedFilters:

export default Ember.Controller.extend(utils, {

    queryParams: ['filter_breadcrumb','filter_price','filter_size_apparel','filter_color'],

    filter_breadcrumb: [],
    filter_price: [],
    filter_size_apparel: [], 
    filter_color: [],

    selectedFilters: Ember.computed('this{filter_breadcrumb,filter_price,filter_size_apparel,filter_color}', function() {
        let filterContainer = {};
        for (let bucket of this.queryParams) {
            let bucketArray = this.get(bucket);
            if (bucketArray.length > 0) { // only add if bucket has values
                filterContainer[bucket] = {
                    'title' : cfg.filterTitles[bucket], // a "pretty name" hash
                    'values' : bucketArray
                };
            }
        }
        return filterContainer;
    })  
});

The contents of selectedFilters would look something like this when a user has chosen filters:

{ 
    filter_breadcrumb: { title: 'Category', values: [ 'Home > Stuff', 'Garage > More Stuff' ] },
    filter_price: { title: 'Price', values: [ '*-20.0' ] },
    filter_color: { title: 'Color', values: [ 'Black', 'Green' ] } 
}

And then the template would be:

<h1>Selected Filters</h1>
{{#each-in selectedFilters as |selectedFilter selectedValues|}}
    {{#each selectedValues.values as |selectedValue|}}
        <strong>{{selectedValues.title}}</strong>: {{selectedValue}} <br>
    {{/each}}
{{/each-in}}

This actually works (kind of). The view is not updating when filters are added and removed. When I hard-refresh the page, they do show up. I'm wondering why they aren't updating even though the "input" properties to selectedFilters do?

I'm thinking either I'm doing it wrong or perhaps there's a better way to do this. Any help appreciated!

Upvotes: 1

Views: 1597

Answers (2)

Ember Freak
Ember Freak

Reputation: 12872

  1. You can't use this for computed property dependent key because it's undefined in that scope.
  2. Arrays and objects defined directly on any Ember.Object are shared across all instances of that object. so initialize it in init(). refer initializing instances ember guide
    init(){
     this._super(...arguments);
     this.set('filter_breadcrumb',[]);
    }
  1. For definining computed properties using arrays as dependant key refer ember guide In your case if you want your computed property to recalculate based array item added/removed or changed to different array then use .[]
    export default Ember.Controller.extend(utils, {
        queryParams: ['filter_breadcrumb', 'filter_price', 'filter_size_apparel', 'filter_color'],
        init(){
            this._super(...arguments);
            this.set("filter_breadcrumb",[]);
            this.set("filter_price",[]);
            this.set("filter_size_apparel",[]);
            this.set("filter_color",[]);        
        },
        selectedFilters: Ember.computed('filter_breadcrumb.[]','filter_price.[]','filter_size_apparel.[]','filter_color.[]', function() {
            let filterContainer = {};
            for (let bucket of this.queryParams) {
                let bucketArray = this.get(bucket);
                if (bucketArray.length > 0) { // only add if bucket has values
                    filterContainer[bucket] = {
                        'title': cfg.filterTitles[bucket], // a "pretty name" hash
                        'values': bucketArray
                    };
                }
            }
            return filterContainer;
        })
    });

In case if you want computed property to recalculate based on each individual item change then consider [email protected]

Upvotes: 3

tarponjargon
tarponjargon

Reputation: 1032

Figured it out. It appears the brace expansion doesn't work on this. I tried:

selectedFilters: Ember.computed('this{filter_breadcrumb,filter_price,filter_size_apparel,filter_color}', function() {

and

selectedFilters: Ember.computed('this.{filter_breadcrumb,filter_price,filter_size_apparel,filter_color}', function() {

This works tho:

selectedFilters: Ember.computed('filter_breadcrumb', 'filter_price', 'filter_size_apparel', 'filter_color', function() {

But I'm still wondering if this is the recommended way of accomplishing my "filter summary" task.

Upvotes: 1

Related Questions