I'm new to Ember and it keeps confusing me about the difference between this.get()
and Ember.get()
. Can someone explain them briefly?
Welcome to Ember ;-)
Every object that extends Ember Observable mixin supports the get()
method (among others).
When you call this.get()
, the this
must refer to such an object (Route, Controller, Component, your own class that extends Ember.Object and so on). Calling get()
on plain object would cause a failure. Let me show the difference:
const emberObjectInstance = Ember.Object.create({
name: 'Bala'
});
emberObjectInstance.get('name'); // returns 'Bala'
const plainObject = { name: 'Bala'};
plainObject.get('name'); // causes a failure since get() is not a function
However, using Ember.get()
successes in both cases:
Ember.get(emberObjectInstance, 'name'); // returns 'Bala'
Ember.get(plainObject, 'name'); // returns 'Bala', too
which can be also written with imports as follows
import { get } from '@ember/object';
get(emberObjectInstance, 'name'); // returns 'Bala'
get(plainObject, 'name'); // returns 'Bala', too
Note: not to forget, calling either of get()
makes computed property get computed (in the most common cases, I don't want to dive deep now - lazy computation, volatile extensions etc), but for the sake of understanding the difference, we can work with plain values.
From own experience, I am using Ember.get()
everywhere I know a plain object might be the object whose property I need to retrieve. A nice example is setupController()
hook into which I may pass plain object from my unit tests to test setupController()
's functionality.
// some route:
setupController(controller, model){
this._super(...arguments);
const name = Ember.get(model, 'name'); // ***
controller.set('isNamePresentOnSetup', Ember.isPresent(name));
}
// in my unit tests I can use plain object:
...
const modelMock = { name: 'Bala' }; // plain object is enough because I use Ember.get instead of model.get() (see ***)?
const controllerMock = Ember.Object.create(); // has to be Ember.Object since I use controller.set() within setupController()
subject.setupController(controllerMock, modelMock);
assert.ok(controllerMock.get('isNamePresentOnSetup'), "property 'isNamePresentOnSetup' set up correctly if model name is present");
...
I could also user Ember.set(controller, 'isNamePresentOnSetup', Ember.isPresent(name))
and then pass plain controller mock into setupController()
, too.
I think this is a good start since you are new in Ember and I am sure Ember gurus would have much more to add. Relevant Ember docs:
https://guides.emberjs.com/v2.9.0/object-model/
https://guides.emberjs.com/v2.9.0/object-model/computed-properties/
https://guides.emberjs.com/v2.9.0/object-model/reopening-classes-and-instances/
UPDATE:
Using get()
with chained paths works different than working with POJOs.
For example in objectInstance.get('a.b.c')
if b
is undefined
the return value is undefined
. Converting this to objectInstance.a.b.c
when b is undefined
would instead raise an exception.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With