Search code examples
javascriptangularjsangularjs-serviceangularjs-factory

Two Factories. One should know when there is a change in Other


Before i state my question, i may be completely wrong with how i am using factories in my use case. Happy to know better alternatives.

So, I have two Factories.

Factory1 takes care of hitting the server, getting and storing that data.

Factory2 does not make any REST Calls. But stores a set of data that would be useful while making REST calls.

Simple question would be, why not Factory1 store that data instead of Factory2. The motive behind Factory2 is that this data would be used by lot of other factories/controllers. So, to remove redundancy this looks a better option.

For now, When a REST call is to be made from Factory1, i can simply do Factory2.getData and then use it. But my use-case is bit more complex. I need Factory1 to fire calls whenever there is a change in Factory2.getData(). We would use $scope normally in case of controllers etc. But how to achieve the same thing here ?

Basically, How to do we know in Factory1 when there is a change in Factory2's data ?

Code:

servicesModule.factory('Factory2', function() {

 var fObj = {},
    filters;

fObj.setFilters = function(fs) {
    filters = fs;
};

fObj.getFilters = function() {
    return filters;
};

return fObj;
});

servicesModule.factory('Factory1', ['$http', '$q', 'Factory2', function($http, $q, Factory2) {
            var fObj = {},
            data;
            fObj.fetchData = function(params) {
                var filters = Factory2.getFilters(); 
                // REST call here and set data to result
            }
            fObj.getData = function(){
                    return data;
            }
    }]);

Solution

  • So, a bit of digging pointed in the direction of $rootScope.

    servicesModule.factory('Factory2', ['$rootScope', function($rootScope) {
    
         var fObj = {},
            filters;
    
        fObj.setFilters = function(fs) {
            filters = fs;
            $rootScope.$emit("FiltersUpdated", fs);
        };
    
        fObj.getFilters = function() {
            return filters;
        };
    
        return fObj;
    }]);
    
    servicesModule.factory('Factory1', ['$http', '$q', 'Factory2', '$rootScope', function($http, $q, Factory2, $rootScope) {
            var fObj = {},
            data;
    
            $rootScope.$on('FiltersUpdated', function(event, data) {
                fObj.fetchData();
            })
    
            fObj.fetchData = function(params) {
                var filters = Factory2.getFilters(); 
                // REST call here and set data to result
            }
            fObj.getData = function(){
                    return data;
            }
    }]);
    

    I would still love to hear others' opinions.