3
votes

How can I list all the attributes defined in a model?

For example, if we have a variant for some imaginary blog application:

App.Post = DS.Model.extend({
    title: DS.attr('string'),
    text: DS.attr('string'),
    comments: DS.hasMany('App.Comment')
});

Then, I am looking for a possibility to iterate over the attributes without having an instance of the App.Post model:

# imaginary function
listAttributes(App.Post)

Such a function could yield an array providing name and type of the model attributes:

[{
    attribute: "title",
    type: "string"
},
{
    attribute: "text",
    type: "string"
}]

How to achieve that with Ember?

3

3 Answers

4
votes

Try this:

var attributes = Ember.get(App.Post, 'attributes');

// For an array of attribute objects:
var attrs = attributes.keys.toArray().map(function(key) {return attributes.get(key);} );

// To print the each attributes name and type:
attrs.forEach(function(attr) {console.log(attr.name, attr.type)});
6
votes

As of Nov 2016 (Ember v2.9.0), the best way to approach this is to use the eachAttribute iterator.

API Reference = http://emberjs.com/api/data/classes/DS.Model.html#method_eachAttribute

modelObj.eachAttribute((name, meta) => {
    console.log('key =' + name);
    console.log('value =' + modelObj.get(name)); 
})
0
votes

Update for current Ember users

Currently the Ember.Map keys and values are private*, so @Mike Grassotti's answer is no longer applicable.

The listAttributes function should look something like this if you don't want to use private objects:

listAttributes(model) {
    const attributes = Ember.get(App.Post, 'attributes'),
          tempArr    = [];

    Ember.get(model.constructor, 'attributes').forEach( (meta, key) =>
        temp.push({attribute: key, type: meta.type})
    );

    return tempArr;
}

* See commit Make Ember.Map keys and values private.