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