javascriptarraysangularjsprototype-pattern

Remove elements from inside Array prototype


I'm trying to extend js native array inside angular service to add some extra features without prototyping global objects.

app.factory('Collection', function($http, $q) {
    var Collection = function(arr) {
        this.key = 'id';
        this._last = 0;
        this._first = 77777777; //just big number.
        this.append(arr);
    }
    Collection.prototype = new Array;
    Collection.prototype.orderBy = function(n, reverse) {
        if (reverse) {
            this.sort(function(a, b) {
                return b[n] - a[n];
            })
        } else {
            this.sort(function(a, b) {
                return a[n] - b[n];
            })
        }
    }
    Collection.prototype.spliceBy = function(key, val) {
        for (var i = 0; i < this.length; i++) {
            if (this[i][key] !== val) {
                this.splice(i, 1); ///THIS NEVER HAPPENS !!
                console.log('removed ' + i + ' from ', this);
            }
        }
    }
    Collection.prototype.subset = function(key, val) {
        return this.filter(function(v) {
            return (v[key] === val);
        });
    }
    Collection.prototype.add = function(obj) {
        for (var i = 0; i < this.length; i++) {
            if (this[i][this.key] > this._last) {
                this._last = this[i][this.key];
            }
            if (this[i][this.key] < this._first) {
                this._first = this[i][this.key];
            }
            if (this[i][this.key] === data[this.key]) {
                if (override) {
                    this[i] = data;
                    console.log('updated uniquePush');
                }
                return i;
                break;
            }
        }
        var id = this.push(data) - 1;
        data._index = id;
        return id;
    }
    return collection
});

This is working fine except for the spliceBy function. I need to filter out elements that does not have value = x; For example in my controller

.controller(function($scope,Collection){

$scope.posts = new Collection;

$scope.posts.add({id:1,type:'post'});
$scope.posts.add({id:2,type:'comment'});

//Collection is now [{id:1,type:post},{id:2,type:comment}];

//i want to remove all comments from array
$scope.posts.spliceBy('type','comment');

});

Yet nothing happens when calling spliceBy :*(


Solution

  • The spliceBy function will not work if you have two elements to remove in a row, because splice is updating the indexes from i to array.length. Try this instead:

    Collection.prototype.spliceBy = function(key, val) {
        var i = this.length;
        while (i--) {
            if (this[i][key] !== val) {
                this.splice(i, 1); ///THIS NEVER HAPPENS !!
                console.log('removed ' + i + ' from ', this);
            }
        }
    }