Class @ember/object

Module: @ember/object

Show:

import { aliasMethod } from '@ember/object';
methodName
String
name of the method to alias

Makes a method available via an additional name.

app/utils/person.js
1
2
3
4
5
6
7
8
9
10
import EmberObject, {
  aliasMethod
} from '@ember/object';

export default EmberObject.extend({
  name() {
    return 'Tomhuda Katzdale';
  },
  moniker: aliasMethod('name')
});
1
2
3
4
let goodGuy = Person.create();

goodGuy.name();    // 'Tomhuda Katzdale'
goodGuy.moniker(); // 'Tomhuda Katzdale'
import { computed } from '@ember/object';
dependentKeys*
String
Optional dependent keys that trigger this computed property.
func
Function
The computed property function.
returns
ComputedProperty
property descriptor instance

This helper returns a new property descriptor that wraps the passed computed property function. You can use this helper to define properties with mixins or via defineProperty().

If you pass a function as an argument, it will be used as a getter. A computed property defined in this way might look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import EmberObject, { computed } from '@ember/object';

let Person = EmberObject.extend({
  init() {
    this._super(...arguments);

    this.firstName = 'Betty';
    this.lastName = 'Jones';
  },

  fullName: computed('firstName', 'lastName', function() {
    return `${this.get('firstName')} ${this.get('lastName')}`;
  })
});

let client = Person.create();

client.get('fullName'); // 'Betty Jones'

client.set('lastName', 'Fuller');
client.get('fullName'); // 'Betty Fuller'

You can pass a hash with two functions, get and set, as an argument to provide both a getter and setter:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import EmberObject, { computed } from '@ember/object';

let Person = EmberObject.extend({
  init() {
    this._super(...arguments);

    this.firstName = 'Betty';
    this.lastName = 'Jones';
  },

  fullName: computed('firstName', 'lastName', {
    get(key) {
      return `${this.get('firstName')} ${this.get('lastName')}`;
    },
    set(key, value) {
      let [firstName, lastName] = value.split(/\s+/);
      this.setProperties({ firstName, lastName });
      return value;
    }
  })
});

let client = Person.create();
client.get('firstName'); // 'Betty'

client.set('fullName', 'Carroll Fuller');
client.get('firstName'); // 'Carroll'

The set function should accept two parameters, key and value. The value returned from set will be the new value of the property.

Note: This is the preferred way to define computed properties when writing third-party libraries that depend on or use Ember, since there is no guarantee that the user will have prototype Extensions enabled.

The alternative syntax, with prototype extensions, might look like:

1
2
3
fullName: function() {
  return this.get('firstName') + ' ' + this.get('lastName');
}.property('firstName', 'lastName')
arguments

Creates an instance of a class. Accepts either no arguments, or an object containing values to initialize the newly instantiated object with.

1
2
3
4
5
6
7
8
9
10
11
12
13
import EmberObject from '@ember/object';

const Person = EmberObject.extend({
  helloWorld() {
    alert(`Hi, my name is ${this.get('name')}`);
  }
});

let tom = Person.create({
  name: 'Tom Dale'
});

tom.helloWorld(); // alerts "Hi, my name is Tom Dale".

create will call the init function if defined during AnyObject.extend

If no arguments are passed to create, it will not set values to the new instance during initialization:

1
2
let noName = Person.create();
noName.helloWorld(); // alerts undefined

NOTE: For performance reasons, you cannot declare methods or computed properties during create. You should instead declare methods and computed properties when using extend.

import { defineProperty } from '@ember/object';
obj
Object
the object to define this property on. This may be a prototype.
keyName
String
the name of the property
desc
Descriptor
an instance of `Descriptor` (typically a computed property) or an ES5 descriptor. You must provide this or `data` but not both.
data
*
something other than a descriptor, that will become the explicit value of this property.

NOTE: This is a low-level method used by other parts of the API. You almost never want to call this method directly. Instead you should use mixin() to define new properties.

Defines a property on an object. This method works much like the ES5 Object.defineProperty() method except that it can also accept computed properties and other special descriptors.

Normally this method takes only three parameters. However if you pass an instance of Descriptor as the third param then you can pass an optional value as the fourth parameter. This is often more efficient than creating new descriptor hashes for each property.

Examples

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import { defineProperty, computed } from '@ember/object';

// ES5 compatible mode
defineProperty(contact, 'firstName', {
  writable: true,
  configurable: false,
  enumerable: true,
  value: 'Charles'
});

// define a simple property
defineProperty(contact, 'lastName', undefined, 'Jolley');

// define a computed property
defineProperty(contact, 'fullName', computed('firstName', 'lastName', function() {
  return this.firstName+' '+this.lastName;
}));
mixins
Mixin
One or more Mixin classes
arguments
Object
Object containing values to use within the new class

Creates a new subclass.

1
2
3
4
5
6
7
import EmberObject from '@ember/object';

const Person = EmberObject.extend({
  say(thing) {
    alert(thing);
   }
});

This defines a new subclass of EmberObject: Person. It contains one method: say().

You can also create a subclass from any existing class by calling its extend() method. For example, you might want to create a subclass of Ember's built-in Component class:

1
2
3
4
5
6
import Component from '@ember/component';

const PersonComponent = Component.extend({
  tagName: 'li',
  classNameBindings: ['isAdministrator']
});

When defining a subclass, you can override methods but still access the implementation of your parent class by calling the special _super() method:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import EmberObject from '@ember/object';

const Person = EmberObject.extend({
  say(thing) {
    let name = this.get('name');
    alert(`${name} says: ${thing}`);
  }
});

const Soldier = Person.extend({
  say(thing) {
    this._super(`${thing}, sir!`);
  },
  march(numberOfHours) {
    alert(`${this.get('name')} marches for ${numberOfHours} hours.`);
  }
});

let yehuda = Soldier.create({
  name: 'Yehuda Katz'
});

yehuda.say('Yes');  // alerts "Yehuda Katz says: Yes, sir!"

The create() on line #17 creates an instance of the Soldier class. The extend() on line #8 creates a subclass of Person. Any instance of the Person class will not have the march() method.

You can also pass Mixin classes to add additional properties to the subclass.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import EmberObject from '@ember/object';
import Mixin from '@ember/object/mixin';

const Person = EmberObject.extend({
  say(thing) {
    alert(`${this.get('name')} says: ${thing}`);
  }
});

const SingingMixin = Mixin.create({
  sing(thing) {
    alert(`${this.get('name')} sings: la la la ${thing}`);
  }
});

const BroadwayStar = Person.extend(SingingMixin, {
  dance() {
    alert(`${this.get('name')} dances: tap tap tap tap `);
  }
});

The BroadwayStar class contains three methods: say(), sing(), and dance().

import { get } from '@ember/object';
obj
Object
The object to retrieve from.
keyName
String
The property key to retrieve
returns
Object
the property value or `null`.

Gets the value of a property on an object. If the property is computed, the function will be invoked. If the property is not defined but the object implements the unknownProperty method then that will be invoked.

1
2
import { get } from '@ember/object';
get(obj, "name");

If you plan to run on IE8 and older browsers then you should use this method anytime you want to retrieve a property on an object that you don't know for sure is private. (Properties beginning with an underscore '_' are considered private.)

On all newer browsers, you only need to use this method to retrieve properties if the property might not be defined on the object and you want to respect the unknownProperty handler. Otherwise you can ignore this method.

Note that if the object itself is undefined, this method will throw an error.

import { getProperties } from '@ember/object';
obj
Object
list
String...|Array
of keys to get
returns
Object

To get multiple properties at once, call getProperties with an object followed by a list of strings or an array:

1
2
3
4
import { getProperties } from '@ember/object';

getProperties(record, 'firstName', 'lastName', 'zipCode');
// { firstName: 'John', lastName: 'Doe', zipCode: '10011' }

is equivalent to:

1
2
3
4
import { getProperties } from '@ember/object';

getProperties(record, ['firstName', 'lastName', 'zipCode']);
// { firstName: 'John', lastName: 'Doe', zipCode: '10011' }
import { getWithDefault } from '@ember/object';
obj
Object
The object to retrieve from.
keyName
String
The name of the property to retrieve
defaultValue
Object
The value to return if the property value is undefined
returns
Object
The property value or the defaultValue.

Retrieves the value of a property from an Object, or a default value in the case that the property returns undefined.

1
2
import { getWithDefault } from '@ember/object';
getWithDefault(person, 'lastName', 'Doe');
import { observer } from '@ember/object';
propertyNames
String
func
Function
returns
func

Specify a method that observes property changes.

1
2
3
4
5
6
7
8
import EmberObject from '@ember/object';
import { observer } from '@ember/object';

export default EmberObject.extend({
  valueObserver: observer('value', function() {
    // Executes whenever the "value" property changes
  })
});

Also available as Function.prototype.observes if prototype extensions are enabled.

Augments a constructor's prototype with additional properties and functions:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import EmberObject from '@ember/object';

const MyObject = EmberObject.extend({
  name: 'an object'
});

o = MyObject.create();
o.get('name'); // 'an object'

MyObject.reopen({
  say(msg) {
    console.log(msg);
  }
});

o2 = MyObject.create();
o2.say('hello'); // logs "hello"

o.say('goodbye'); // logs "goodbye"

To add functions and properties to the constructor itself, see reopenClass

Augments a constructor's own properties and functions:

1
2
3
4
5
6
7
8
9
10
11
12
import EmberObject from '@ember/object';

const MyObject = EmberObject.extend({
  name: 'an object'
});

MyObject.reopenClass({
  canBuild: false
});

MyObject.canBuild; // false
o = MyObject.create();

In other words, this creates static properties and functions for the class. These are only available on the class and not on any instance of that class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import EmberObject from '@ember/object';

const Person = EmberObject.extend({
  name: '',
  sayHello() {
    alert(`Hello. My name is ${this.get('name')}`);
  }
});

Person.reopenClass({
  species: 'Homo sapiens',

  createPerson(name) {
    return Person.create({ name });
  }
});

let tom = Person.create({
  name: 'Tom Dale'
});
let yehuda = Person.createPerson('Yehuda Katz');

tom.sayHello(); // "Hello. My name is Tom Dale"
yehuda.sayHello(); // "Hello. My name is Yehuda Katz"
alert(Person.species); // "Homo sapiens"

Note that species and createPerson are not valid on the tom and yehuda variables. They are only valid on Person.

To add functions and properties to instances of a constructor by extending the constructor's prototype see reopen

import { set } from '@ember/object';
obj
Object
The object to modify.
keyName
String
The property key to set
value
Object
The value to set
returns
Object
the passed value.

Sets the value of a property on an object, respecting computed properties and notifying observers and other listeners of the change. If the specified property is not defined on the object and the object implements the setUnknownProperty method, then instead of setting the value of the property on the object, its setUnknownProperty handler will be invoked with the two parameters keyName and value.

1
2
import { set } from '@ember/object';
set(obj, "name", value);
import { setProperties } from '@ember/object';
obj
properties
Object
returns
properties

Set a list of properties on an object. These properties are set inside a single beginPropertyChanges and endPropertyChanges batch, so observers will be buffered.

1
2
3
4
5
6
7
8
import EmberObject from '@ember/object';
let anObject = EmberObject.create();

anObject.setProperties({
  firstName: 'Stanley',
  lastName: 'Stuart',
  age: 21
});
import { trySet } from '@ember/object';
root
Object
The object to modify.
path
String
The property path to set
value
Object
The value to set

Error-tolerant form of set. Will not blow up if any part of the chain is undefined, null, or destroyed.

This is primarily used when syncing bindings, which may try to update after an object has been destroyed.

1
2
3
4
import { trySet } from '@ember/object';

let obj = { name: "Zoey" };
trySet(obj, "contacts.twitter", "@emberjs");