Repository: petebacondarwin/angular-toArrayFilter Branch: master Commit: c1d4ec06870d Files: 9 Total size: 10.1 KB Directory structure: gitextract_9xn72n5w/ ├── .gitignore ├── CHANGELOG.md ├── README.md ├── bower.json ├── index.js ├── package.json ├── test/ │ ├── karma.conf.js │ └── toArrayFilter.spec.js └── toArrayFilter.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ node_modules bower_components .idea/ ================================================ FILE: CHANGELOG.md ================================================ # Change Log ## v1.0.2 - Support commonjs ## v1.0.2 - Move dependencies into devDependencies ## v1.0.1 ### Bug fixes * fix(toArrayFilter): handle non-objects 9bc79dd1 * fix(toArrayFilter): ignore 'undefined' and `null` for better binding support *Brian Gray* **8bfd99c8** ## v1.0.0 First release ================================================ FILE: README.md ================================================ # AngularJS toArray Filter Although AngularJS 1.x supports iterating over an object (keys and values), it is not the preferred way of doing things. Moreover, filters like `filter` and `orderBy` just don't work with objects; they are designed to work with arrays. This filter can convert your objects into stable arrays that can then be filtered and sorted using the standard AngularJS filters. ## Get It The easiest way to install is using [bower][bower]: ``` bower install --save angular-toArrayFilter ``` You can also install via [npm][npm] ``` npm install --save angular-toarrayfilter ``` Alternatively you can download from the GitHub project: [https://github.com/petebacondarwin/angular-toArrayFilter](https://github.com/petebacondarwin/angular-toArrayFilter) ## Load It Load the `toArrayFilter.js` file into your web app after loading `angular.js` ```html ... ... ... ... ``` ## Use It Make sure that your AngularJS application references the `angular-toArrayFilter` module: ``` angular.module('myApp', ['angular-toArrayFilter']); ``` Now if you have an object that you wish to repeat over, just slip the `toArray` filter in before you try sorting or filtering: ```html
{{ item.$key }} - {{ item.someProp }}
``` ## How it works The filter iterates over the object's keys and creates an array containing the value of each property. By default, the filter also attaches a new property `$key` to the value containing the original key that was used in the object we are iterating over to reference the property. ## Not adding the `$key` property If you don't want the `$key` property to be attached to each of the property values, you simply put an additional parameter on the `toArray` filter: ```html
{{ item.someProp }} (no $key available now)
``` ## Using `$key` with non-objects Non-objects such as strings and numbers cannot have a new `$key` property attached to them. If the object properties you are iterating over are not objects then you must either disable the `$key` property or the filter will replace the non-object with a new object of the form: `{ $key: key, $value: value }`. ## Caveats There are always issues when trying to iterate over properties in JavaScript and the `toArray` filter has its own set of things to be aware of when using it: * It only works with plain Objects - don't try to filter arrays and strings with it. * If you don't disable it, the filter will modify each property value with a new `$key` property. * This filter is not compatible with IE8. (It uses `Object.keys` and `Object.defineProperty` which don't work well or at all in Internet Explorer 8 (IE8). ## Example Here is a fuller example of using the `toArray` filter on an object, to allow sorting and filtering by a `date` property on each property of the original object. It also demonstrates how you can easily update the original object and the array will stay in sync. Check out the [Live Demo][live-demo] **index.html:** ```html
{{item.$key}}: {{item.date | date}}
``` **app.js** ```js angular.module('app', []) .controller('Main', function Main($scope) { $scope.nextKey = 4; $scope.items = { 0: {date: new Date('12/23/2013')}, 1: {date: new Date('12/23/2011')}, 2: {date: new Date('12/23/2010')}, 3: {date: new Date('12/23/2015')} }; $scope.remove = function(item) { delete $scope.items[item.$key]; }; $scope.add = function() { $scope.items[$scope.nextKey] = { date: new Date() }; $scope.nextKey += 1; }; }); ``` [bower]: https://bower.io [live-demo]: http://plnkr.co/edit/G69YqKb9ag1qPLVqE6wz?p=preview ================================================ FILE: bower.json ================================================ { "name": "angular-toArrayFilter", "main": "toArrayFilter.js", "version": "1.0.1", "homepage": "https://github.com/petebacondarwin/angular-toArrayFilter", "authors": [ "Peter Bacon Darwin " ], "description": "An angular filter to convert objects to arrays for easy filtering and sorting", "keywords": [ "angular", "filter", "toArray", "object", "sort", "orderBy" ], "license": "MIT", "ignore": [ "**/.*", "node_modules", "bower_components", "test", "tests" ], "dependencies": { "angular": ">=1.2.0" }, "devDependencies": { "angular-mocks": ">=1.2.0" } } ================================================ FILE: index.js ================================================ require('./toArrayFilter'); module.exports = 'angular-toArrayFilter'; ================================================ FILE: package.json ================================================ { "name": "angular-toarrayfilter", "version": "1.0.3", "description": "An angular filter to convert objects to arrays for easy filtering and sorting", "main": "index.js", "directories": { "test": "test" }, "dependencies": {}, "devDependencies": { "karma": "^0.12.19", "karma-chrome-launcher": "^0.1.4", "karma-jasmine": "^0.1.5" }, "scripts": { "test": "karma start test/karma.conf.js" }, "repository": { "type": "git", "url": "https://github.com/petebacondarwin/angular-toArrayFilter.git" }, "keywords": [ "angular", "filter", "toArray", "sort", "orderBy" ], "author": "Pete Bacon Darwin ", "license": "MIT", "bugs": { "url": "https://github.com/petebacondarwin/angular-toArrayFilter/issues" }, "homepage": "https://github.com/petebacondarwin/angular-toArrayFilter" } ================================================ FILE: test/karma.conf.js ================================================ // Karma configuration // Generated on Sun Aug 03 2014 23:08:18 GMT+0100 (BST) module.exports = function(config) { config.set({ // base path that will be used to resolve all patterns (eg. files, exclude) basePath: '..', // frameworks to use // available frameworks: https://npmjs.org/browse/keyword/karma-adapter frameworks: ['jasmine'], // list of files / patterns to load in the browser files: [ 'bower_components/angular/angular.js', 'bower_components/angular-mocks/angular-mocks.js', 'toArrayFilter.js', 'test/**/*.js' ], // list of files to exclude exclude: [ ], // preprocess matching files before serving them to the browser // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor preprocessors: { }, // test results reporter to use // possible values: 'dots', 'progress' // available reporters: https://npmjs.org/browse/keyword/karma-reporter reporters: ['progress'], // web server port port: 9876, // enable / disable colors in the output (reporters and logs) colors: true, // level of logging // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG logLevel: config.LOG_INFO, // enable / disable watching file and executing tests whenever any file changes autoWatch: true, // start these browsers // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher browsers: ['Chrome'], // Continuous Integration mode // if true, Karma captures browsers, runs the tests and exits singleRun: false }); }; ================================================ FILE: test/toArrayFilter.spec.js ================================================ describe("toArrayFilter", function() { beforeEach(module('angular-toArrayFilter')); it("should convert an object to an array of values", inject(function(toArrayFilter) { var obj = { a: { name: 'A' }, b: { name: 'B' }, c: { name: 'C' } }; expect(toArrayFilter(obj)).toEqual([ { $key: 'a', name: 'A' }, { $key: 'b', name: 'B' }, { $key: 'c', name: 'C' } ]); })); it("should not include $key if `addKey` param is false", inject(function(toArrayFilter) { var obj = { a: { name: 'A' }, b: { name: 'B' }, c: { name: 'C' } }; expect(toArrayFilter(obj, false)).toEqual([ { name: 'A' }, { name: 'B' }, { name: 'C' } ]); })); it("should work with non-object properties if $key is disabled", inject(function(toArrayFilter) { var obj = { a: 'A', b: 'B', c: 'C' }; expect(toArrayFilter(obj, false)).toEqual([ 'A', 'B', 'C' ]); })); it("should create new objects ({$key:...,$value:...}) from non-object properties if `addKey` is not false", inject(function(toArrayFilter) { var obj = { a: 'A', b: 'B', c: 'C' }; expect(toArrayFilter(obj)).toEqual([ { $key: 'a', $value: 'A' }, { $key: 'b', $value: 'B' }, { $key: 'c', $value: 'C' } ]); })); it("should work with an array", inject(function(toArrayFilter) { var obj = [ { name: 'A' }, { name: 'B' }, { name: 'C' } ]; expect(toArrayFilter(obj)).toEqual([ { $key: '0', name: 'A' }, { $key: '1', name: 'B' }, { $key: '2', name: 'C' } ]); })); it("should handle invalid inputs", inject(function(toArrayFilter) { expect(toArrayFilter(undefined)).toBeUndefined(); expect(toArrayFilter(null)).toBe(null); expect(toArrayFilter('some string')).toBe('some string'); expect(toArrayFilter(12345)).toBe(12345); })); }); ================================================ FILE: toArrayFilter.js ================================================ angular.module('angular-toArrayFilter', []) .filter('toArray', function () { return function (obj, addKey) { if (!angular.isObject(obj)) return obj; if ( addKey === false ) { return Object.keys(obj).map(function(key) { return obj[key]; }); } else { return Object.keys(obj).map(function (key) { var value = obj[key]; return angular.isObject(value) ? Object.defineProperty(value, '$key', { enumerable: false, value: key}) : { $key: key, $value: value }; }); } }; });