Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reflection on EmberJS objects? How to find a list of property keys without knowing the keys in advance

Tags:

ember.js

Is there a way to retrieve the set-at-creations properties of an EmberJS object if you don't know all your keys in advance?

Via the inspector I see all the object properties which appear to be stored in the meta-object's values hash, but I can't seem to find any methods to get it back. For example object.getProperties() needs a key list, but I'm trying to create a generic object container that doesn't know what it will contain in advance, but is able to return information about itself.

like image 469
Seb Barre Avatar asked Feb 09 '12 13:02

Seb Barre


4 Answers

I haven't used this in production code, so your mileage may vary, but reviewing the Ember source suggests two functions that might be useful to you, or at least worth reviewing the implementation:

Ember.keys: "Returns all of the keys defined on an object or hash. This is useful when inspecting objects for debugging. On browsers that support it, this uses the native Object.keys implementation." Object.keys documentation on MDN

Ember.inspect: "Convenience method to inspect an object. This method will attempt to convert the object into a useful string description." Source on Github

like image 95
Luke Melia Avatar answered Nov 02 '22 00:11

Luke Melia


I believe the simple answer is: you don't find a list of props. At least I haven't been able to.

However I noticed that ember props appear to be prefixed __ember, which made me solve it like this:

for (f in App.model) { 
    if (App.model.hasOwnProperty(f) && f.indexOf('__ember') < 0) { 
       console.log(f);
    }
 };

And it seems to work. But I don't know whether it's 100% certain to not get any bad props.

EDIT: Adam's gist is provided from comments. https://gist.github.com/1817543

var getOwnProperties = function(model){
  var props = {};
  for(var prop in model){
    if( model.hasOwnProperty(prop) 
        && prop.indexOf('__ember') < 0
        && prop.indexOf('_super') < 0
        && Ember.typeOf(model.get(prop)) !== 'function'
    ){
      props[prop] = model[prop];
    }
  }
  return props;
}
like image 30
Martin Algesten Avatar answered Nov 01 '22 22:11

Martin Algesten


Neither of these answers are reliable, unfortunately, because any keys paired with a null or undefined value will not be visible.

e.g.

MyClass = Ember.Object.extend({
    name: null,
    age: null,
    weight: null,
    height: null
});
test = MyClass.create({name: 'wmarbut'});
console.log( Ember.keys(test) );

Is only going to give you

["_super", "name"]

The solution that I came up with is:

/**
* Method to get keys out of an object into an array
* @param object obj_proto The dumb javascript object to extract keys from
* @return array an array of keys
*/
function key_array(obj_proto) {
    keys = [];
    for (var key in obj_proto) {
        keys.push(key);
    }
    return keys;
}


/*
* Put the structure of the object that you want into a dumb JavaScript object
* instead of directly into an Ember.Object
*/
MyClassPrototype = {
    name: null,
    age: null,
    weight: null,
    height: null
}

/*
* Extend the Ember.Object using your dumb javascript object
*/
MyClass = Ember.Object.extend(MyClassPrototype);

/*
* Set a hidden field for the keys the object possesses
*/
MyClass.reopen({__keys: key_array(MyClassPrototype)});

Using this method, you can now access the __keys field and know which keys to iterate over. This does not, however, solve the problem of objects where the structure isn't known before hand.

like image 5
wmarbut Avatar answered Nov 01 '22 23:11

wmarbut


I use this:

Ember.keys(Ember.meta(App.YOUR_MODEL.proto()).descs)
like image 5
Pheonix Avatar answered Nov 01 '22 22:11

Pheonix