harryBundles
harryBundles

Reputation: 158

Comparing objects between 2 arrays in Angularjs

I'm trying to figure the best way to do this, given that there will be a lot of data and I don't want to have giant loops hogging up resources. I have a lot of regular javascript/jquery experience, but am new to Angular and want to do it with Angularjs best practices.

I have a list of items and users can "favorite" them. When viewing all items, I'd like to show the ones that favorited by marking them with an indicator. Both items and favorites are in separate tables and returned as JSON with different IDs.

JS:

$scope.favorites = [];//$http.get of JSON file
$scope.items = [];//$http.get of JSON file

$scope.isFavorite = function(itemId) {
    var len = $scope.favorites. !== 'undefined' ? $scope.favorites.length : 0;
    for(var i = 0; i < len; i++) {
        if($scope.favorites[i].id === itemId) {
            return true;
        }
    }
};

HTML:

<div ng-repeat="item in items">
    <i ng-class="isFavorite(item.id) ? 'icon-bookmark' : 'icon-bookmark-empty'"></i>
</div>

I have a couple other checks for "isFavorite" so I'm trying to figure the best way to compare the 2 without checking every time in a loop. Any suggestions?

Upvotes: 1

Views: 4139

Answers (1)

romiem
romiem

Reputation: 8930

The most optimal way I can think of would be to modify the $scope.items array once the favourites http request has returned it's data, and set a 'favourite' boolean property on each item.

That way, your isFavourite method will not trigger on each digest cycle. For example:

var promises = [$http.get('/items'), $http.get('/favourites')];

$q.all(promises).then(function (resultsArray) {

    $scope.items = resultsArray[0];
    var favourites = resultsArray[1];

    $scope.items.forEach(function (item) {
        var matches = favourites.filter(function (f) {
                return f.id === item.id;
            });
        item.favourite = matches.length ? true : false;
    });

});

It's also worth bearing in mind that you probably want to wrap both http requests in a $q.all method so that you can fire a single callback once both http requests have finished.

EDIT: updated to show full code with $q.all implementation

Upvotes: 2

Related Questions