How to add a computed property with a setter in Ember 3.5+?

#1

I have recently upgraded my Ember app from 2.18 to 3.4 and now get this deprecation:

[DEPRECATED] computed property 'xxx' was not set on object 'yyy' via 'defineProperty'

I am defining computed properties onto the prototype of a class at runtime. Currently like this:

prototype[attribute] = computed(...observableProperties, {
    get(key) {
        ...
    },
    set(key, value) {
        ...
    },
}));

The deprecation advises to use defineProperty as a replacement, but if I do this

defineProperty(prototype, attribute, computed(...observableProperties, {
    get(key) {
        ...
    },
    set(key, value) {
        ...
    },
}));

Then the getter works fine but the setter is not added to the property and I get this error

Cannot set property xxx of [object Object] which has only a getter

I took at look into how defineProperty is defined and it only seems to set the getter. (from ember-metal/lib/properties.ts:192)

    Object.defineProperty(obj, keyName, {
      configurable: true,
      enumerable,
      get: DESCRIPTOR_GETTER_FUNCTION(keyName, value),
    });

I tried using Mixin instead of defineProperty but that ultimately executed the same Object.defineProperty.

How can I add a computed property with a setter in Ember 3.x? I can live with the deprecation in Ember 3.4 but in 3.5 the deprecated functionality is removed. Thanks for any advice!

#2

Does anyone have any idea on this? Should I raise an issue on the main repo? Or maybe I need to raise an RFC to have this functionality formally added to defineProperty?

#3

Can you share the full class you’re trying to place a computed property on?

#4

Hey, I setup a quick example to reproduce this issue and define property seems to work just fine with the set property. Example twiddle here.

Can you share a little more of what you’re doing around the define property call?

#5

Are you using Object.defineProperty or Ember.defineProperty? In order to get computed properties to work, you should be using Ember.defineProperty (or import { defineProperty } from '@ember/object'; )

1 Like