Dynamic computes


#1

Is there such as thing as dynamic computed properties? I think a bit of code would make more sense.

Let’s say there is an object like this:

const fruitVendor = {
    weeks: {
        '2018-10-07': {
            available: ['apples', 'bananas', 'pears']
        },
        ...
    },
    ...
}

The data will always be in this format: fruitVendor.weeks.<YYYY-MM-DD>.available.

There could be a lot weeks, but I may only care about a computed property on this week. Right now I need to do something like this:

myComputedProperty: computed('fruitVendor.weeks', ...)

Whereas, ideally, I had something like this:

myComputedProperty: computed('fruitVendor.weeks.<getThisWeek()>.available', ...)

How do you handle something like this?


#2

You could use another computed with a second dependent key on the week of interest?

@computed('weeks', 'selectedWeek')
get someData() {
  return this.weeks[this.selectedWeek];
}

#3

Thanks. I will try this.


#4

Sometimes in these cases, things get simpler if you replace some of your computed properties with helpers.


#5

This is quite easy to do in plain ember once you get your head around it:

There’s also an addon but I haven’t tried it:


#6

Thanks @alexspeller. While I didn’t do it exactly like in the linked article, I used defineProperty in init so it is something like this:

    init() {
        this._super(...arguments);
        const currentWeek = this.get('week');
        defineProperty(this, '_availableCurrentWeek', computed.oneWay(`fruitVendor.weeks.${currentWeek}.available`));
    },

#7

I would suggest not using “defineProperty”.

In docs you can find sentence:

“NOTE: This is a low-level method used by other parts of the API. You almost never want to call this method directly.”

But you cen easily set property

init() {
        this._super(...arguments);
        const currentWeek = this.get('week');
        set(this, '_availableCurrentWeek', computed.oneWay(`fruitVendor.weeks.${currentWeek}.available`));
    },