diff --git a/src/_filter/collection/group-by.js b/src/_filter/collection/group-by.js index 868285a..96dd0f4 100644 --- a/src/_filter/collection/group-by.js +++ b/src/_filter/collection/group-by.js @@ -5,16 +5,23 @@ * * @description * Create an object composed of keys generated from the result of running each element of a collection, - * each key is an array of the elements. + * each key is an array of the elements. Specify null replacement to control sort behavior for null/undefined keys. */ angular.module('a8m.group-by', [ 'a8m.filter-watcher' ]) .filter('groupBy', [ '$parse', 'filterWatcher', function ( $parse, filterWatcher ) { - return function (collection, property) { + return function (collection, property, nullReplacement) { var result, - get = $parse(property), + getParse = $parse(property), + get = function(el) { + var val = getParse(el); + if(nullReplacement !== undefined && (val == null || val == undefined)){ + return nullReplacement; + } + return val; + }, prop; if(!isObject(collection) || isUndefined(property)) { diff --git a/test/spec/filter/collection/group-by.js b/test/spec/filter/collection/group-by.js index 2b04ec2..0741aa8 100644 --- a/test/spec/filter/collection/group-by.js +++ b/test/spec/filter/collection/group-by.js @@ -73,4 +73,66 @@ describe('groupByFilter', function() { }); + it('should replace null when asked, get array as collection, property(nested to) as identifier and ' + + 'returns the composed aggregate object.', function() { + + var players = [ + {name: 'Gene', team: 'alpha'}, + {name: 'George', team: 'beta'}, + {name: 'Steve', team: 'gamma'}, + {name: 'Paula', team: 'beta'}, + {name: 'Scruath', team: 'gamma'}, + {name: 'Alex', team: null }, + {name: 'Rob' }, + {name: 'Sven', team: false } + ]; + + expect(filter(players, 'team', 'a')).toEqual( { + a: [players[5], players[6]], + alpha: [players[0]], + beta: [players[1], players[3]], + gamma: [players[2], players[4]], + 'false': [players[7]] + }); + + }); + + it('should replace null when asked, support nested properties to', function() { + var orders = [ + { id:10, customer: { name: 'foo', id: 1 } }, + { id:11, customer: { name: 'bar', id: 2 } }, + { id:12, customer: { name: 'foo', id: 1 } }, + { id:13, customer: { name: 'bar', id: 2 } }, + { id:14, customer: { name: 'bar', id: 3 } }, + { id:15, customer: { name: null } }, + { id:16, customer: {} }, + 2, null, true + ]; + + expect(filter(orders, 'customer.name', 0)).toEqual( { + foo: [orders[0], orders[2]], + bar: [orders[1], orders[3], orders[4]], + 0: [orders[5], orders[6], 2, null, true] + }); + + }); + + + it('should replace null when asked, get object as collection, property(nested to) as identifier and ' + + 'returns the composed aggregate object.', function() { + var dataObject = { + 0: { id: 1, data: {} }, + 1: { id: 1, data: {} }, + 2: { id: 2, data: {} }, + 3: { id: 2, data: {} }, + 4: { id: null, data: {} } + }; + + expect(filter(dataObject, 'id', 0)).toEqual({ + 0: [dataObject[4]], + 1: [dataObject[0], dataObject[1]], + 2: [dataObject[2], dataObject[3]] + }); + + }); });