Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have an AngularJS service that is keeping track of an array of items, which are added and removed through exposed methods by several controllers. Surely, the view should always have the latest data.

At the moment I use the straight-forward solution of exposing the array to the controllers, so that they can directly bind to this array. While it works and seems to be a common solution it leaves me with the feeling that this is far from the cleanest solution possible.

Preferably, I would like to encapsulate the array and simply have the controllers be notified about updates so that they can pull the data when needed avoiding situations where a controller could manipulate the array without using the proper methods.

I was looking for patterns to solve this problem but couldn't find any that would be better than the status-quo. Can anyone pinpoint me to a pattern?

    myapp.service('favoritesService', ['$http', '$q', function(http, q) {

    var favorites = null;
    var self = this;

    this.receiveFavorites = function(forceReload) {
        if(forceReload || favorites === null) {
            return http.get('/user/favorites').then(function (returnData) {
                    favorites = angular.copy(returnData.data.favorites, favorites);
                    return favorites;
                });
        } else {
            var deferred = q.defer();
            deferred.resolve(favorites);
            return deferred.promise;
        }
    };

    this.addFavorite = function(path) {
        if(!path || !path.length)
            return q.reject("No path provided");
        var favId = getIdForPath(path);
        if(favId !== null) {
            var deferred = q.defer();
            deferred.resolve(favId);
            return deferred.promise;
        }
        var name = new Path(path).basename();
        return http.put('/user/favorite.json', 
                        {   path: path,
                            name: name
                        }).then(function(returnData) {
                            return self.receiveFavorites(true);
                        })
    },

    this.removeFavorite = function(path) {
        var favIndex = getIndexForPath(path);
        var favId = favorites[favIndex]._id.toString();
        if(favIndex === null || favId === null)
            return q.reject("Favorite doesn't exist");

        return http.delete('/user/favorites/' + favId).success(function(data) {
            favorites.splice(favIndex, 1);
        });
    };
}]);
share|improve this question
1  
controller could manipulate the array without using the proper methods. Please explain scenario where this could happen. –  charlietfl Dec 28 '13 at 14:56
    
I think binding to the array is the best plan given that is the power of AngularJS. If you really want to have the controller react in a specific way, consider a watcher on the array within the controller. –  Chris Story Dec 28 '13 at 16:30
    
@charlietfl - At a later stage, someone might forget about the embedded routines in the service and directly modify the array to e.g. remove an item. As a result, there would be no synchronisation with the server anymore –  florian Dec 28 '13 at 23:01
    
asuming you are using any sort of ng-repeat in html, have to expose array to controller regardless –  charlietfl Dec 28 '13 at 23:07

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.