A group by computed property and helper that supports nested properties, e.g. model with a
belongsTo
relationship.
import Controller from '@ember/controller';
import { groupByPath } from 'ember-cli-group-by/macros';
export default Controller.extend({
arrayGrouped: groupByPath('array', 'nested.property'),
});
Requires Ember 2.10 or higher, see Issue #2.
ember install ember-cli-group-by
Computed property
import Controller from '@ember/controller';
import { A } from '@ember/array';
import { groupByPath } from 'ember-cli-group-by/macros';
export default Controller.extend({
cartGrouped: groupByPath('cart', 'category'),
init() {
this._super(...arguments);
this.set('cart', A([
{ name: 'Cinnamon ', category: 'Spice' },
{ name: 'Banana', category: 'Fruit' },
{ name: 'Apple', category: 'Fruit' },
{ name: 'Lettuce', category: 'Vegetable' },
{ name: 'Broccoli', category: 'Vegetable' },
]);
},
});
Handlebars helper
import Controller from '@ember/controller';
import { A } from '@ember/array';
export default Controller.extend({
init() {
this._super(...arguments);
this.set('cart', A([
{ name: 'Cinnamon ', category: 'Spice' },
{ name: 'Banana', category: 'Fruit' },
{ name: 'Apple', category: 'Fruit' },
{ name: 'Lettuce', category: 'Vegetable' },
{ name: 'Broccoli', category: 'Vegetable' },
]);
},
});
The group name for an item can be overridden by implementing a computed property function or by passing a closure action to the helper.
Computed property
import Controller from '@ember/controller';
import { A } from '@ember/array';
import { isNone } from '@ember/utils';
import { groupByPath } from 'ember-cli-group-by/macros';
export default Controller.extend({
cartGrouped: groupByPath('cart', 'category', function (value) {
return isNone(value) ? 'Other' : value;
}),
init() {
this._super(...arguments);
this.set('cart', A([
{ name: 'Cinnamon ', category: 'Spice' },
{ name: 'Banana', category: 'Fruit' },
{ name: 'Apple', category: 'Fruit' },
{ name: 'Lettuce', category: 'Vegetable' },
{ name: 'Broccoli', category: 'Vegetable' },
{ name: 'Salt', category: null },
{ name: 'Sugar' },
]);
},
});
Handlebars helper
import Controller from '@ember/controller';
import { A } from '@ember/array';
import { isNone } from '@ember/utils';
export default Controller.extend({
init() {
this._super(...arguments);
this.set('cart', A([
{ name: 'Cinnamon ', category: 'Spice' },
{ name: 'Banana', category: 'Fruit' },
{ name: 'Apple', category: 'Fruit' },
{ name: 'Lettuce', category: 'Vegetable' },
{ name: 'Broccoli', category: 'Vegetable' },
{ name: 'Salt', category: null },
{ name: 'Sugar' },
]);
},
actions: {
defaultCategory(value) {
return isNone(value) ? 'Other' : value;
},
},
});
The group by property path can be a nested belongsTo
relationship that is loaded asynchronously.
Check out the example at ember-twiddle.
// models/user.js
export default Model.extend({
fullname: attr('string'),
cart: hasMany('product', { inverse: 'shopper' }),
});
// models/product.js
export default Model.extend({
name: attr('string'),
category: belongsTo('category'),
shopper: belongsTo('user', { inverse: 'cart' }),
});
// models/category.js
export default Model.extend({
name: attr('string'),
});
import Controller from '@ember/controller';
import { isNone } from '@ember/utils';
import { alias } from '@ember/object/computed';
import { groupByPath } from 'ember-cli-group-by/macros';
export default Controller.extend({
user: alias('model'),
cart: alias('user.cart'),
cartGrouped: groupByPath('cart', 'category.name', function (value) {
return isNone(value) ? 'Other' : value;
}),
});