You probably don't need to wrap in Ember.Object

I have seen several posts lately where people share code that does things like:

this.set(‘recipientList’, Ember.Object.create(response)).

And rather than hijack those threads, I’m starting a new one to point out: you almost certainly don’t need that Ember.Object.create.

Ember works fine with Plain Old Javascript Objects (POJOs). If you already have a POJO, you can just use the POJO.

The only rule you need to follow to make sure Ember can keep track of your data changing is that you use set to change it. For example, this template:

The value is {{pojo.outside.inside.value}}

Will always render fine and stay up to date even if you implement the component like this:

import { set } from '@ember/object';
import Component from '@ember/component';
export default Component.extend({
  init() {
    this._super();
    this.set('pojo', { outside: { inside: { value: 'a' } } });
  },
  actions: {
     changeIt() {
        set(this.pojo.outside.inside, 'value', 'b');
     }
  }
});

When should you wrap in Ember.Object? Only when you actually want to extend Ember.Object to use a feature like computed properties. If you aren’t extending and you’re just calling Ember.Object.create(...), you almost certainly don’t need to.

5 Likes

I’ve struggled a bit with folks doing this as well. The most common response is that other code “breaks” because it is calling .get on some foreign object. IMHO, that is the bug to fix, not swapping to Ember.Object.create()

Relatedly, is the eslint-plugin-ember rule use-ember-get-and-setwhich should be used with ignoreThisExpressions: true configuration. This will help prevent situations mentioned above where you are arbitrarily calling someObj.get('some.path.here'), but still allows the very common this.get / this.set scenarios.

3 Likes