Ember 1.8: "You must use Ember.set() to set the property"


#1

Hello, after upgrading Ember to 1.8 i get this error:

Error: Assertion Failed: You must use Ember.set() to set the `current` property (of <(unknown mixin):ember541>) to `[object Object]`.

This seems to happen when i try to set a property defined in the prototype of a subclass of Ember.Object.

Is this really necessary? this property is not exposed to any template, and i dont need computed properties/observers on it; it is used for private state of the class.


#2

This error is only triggered when the property is being watched (by an observer or computed property).

Code setting up the mandatory setter property is here (note that this is only setup in the Ember.watch code path when a property is watched).


#3

Solution: adding a underscore prefix to the property name fixes this.

Example:

// code working on 1.7
Em.Object.extend({
    current: null,
    method: function() {
        this.current = {};
    }
});

// in 1.8 becomes
Em.Object.extend({
    _current: null,
    method: function() {
        this._current = {};
    }
});

#4

Thanks for your reply.

Unfortunately, as i previously said, this property is used internally in the class. I didnt add code to register any observer and there are no computed properties that depend on it (ive posted after reading the changelog about MANDATORY_SETTER).

I have a lot of code done this way that didnt caused any errors (so far) after upgrading, but mosty they reside in mixins (part of the prototype?), and this class (the one that caused the error) is used as a service (injected via container); i will look if this causes problems with my other service classes (the container adds observers?).

Also, seems like setting properties this way inside init does not trigger the error.


#5

Throw a breakpoint in the line of code that I referenced above, inspect the stack to see where Ember.watch is being called from. See “who/what” is watching the objects current property (it is being watched or this assertion would not have been setup).


#6

Thank you for the help; it was hard to find, but in fact there was an observer.

The cause is that i was testing the service object manually via $E, the variable thrown by the Ember Inspector (from the “Container” tab). When you click any object from there, it adds an observer for every property whose name does not begin with an underscore.

I think it is necessary to document this (or fix?), because if you open the inspector, a lot of code may suddenly break.


#7

I already reported this bug. I’m not sure why it’s blocking status was removed, but it was supposed to block the 1.8 release


#8

I believe that the bug you are referring to is https://github.com/emberjs/ember.js/issues/9387, which is not related to the issue reported (which was that the mandatory setter assertion is thrown but no obvious observers were setup).


#9

Sorry if im wrong, but https://github.com/emberjs/ember.js/issues/9387 is about a bug in Ember (as @rwjblue said), and the one that im reporting here is caused by the Ember Inspector (not Ember per se) because the way it works contradicts the 1.8 philosophy of forcing usage of set in application code for properties that requires observers/computed properties.

Meanwhile can the inspector be updated to workaround this or remove this flag by default in 1.8?


#10

Yes, I think it should probably be looked at from the inspector perspective.

Ping @teddyzeenny


#11

This is not related to $E, but to the object inspector. When you send and object to the object inspector, we set up observers on these properties to keep them up to date. Setting the property directly (without .set) will cause the object inspector to be out of sync (which would be unexpected behavior). The mandatory setter complaining seems like the correct behavior to me.

I don’t think setting a (public) property directly is a good idea (even if there are no current observers, you might add some in the future, or need to observe them indirectly; example: object inspector).


#12

Im using ember-cli but since it does not build Ember i cant disable the flag. I would like to use 1.8 and the Inspector, but without refactoring application code to rename private properties with an underscore prefix.

Is there another way i can fix this or should i stick with 1.7?

For mantaining backwards compatibility with existing code, a hackish proposal for the Inspector:

If the flag mandatory-setter is enabled, for every property guessed as public (no underscore prefix) that also does not have Ember metadata (raw JS properties that never got called get or set on them and have no observers), add a timer to check regularly if they acquire metadata, and if this happens, register observers as normal.


#13

Thank you so much sarasa. Your solution solved a problem of mine I had for days. Thumbs up!