Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how can i extend a service

I am fairly new to angularjs and am not able to find any documentation or examples for this. What I am looking to do is to extend a basic service so that i can use the methods defined under the basic service from other services. So for example say i have a basic service as follows.

angular.module('myServices', []).

    factory('BasicService', function($http){
        var some_arg = 'abcd'
        var BasicService = {
            method_one: function(arg=some_arg){ /*code for method one*/},
            method_two: function(arg=some_arg){ /*code for method two*/},
            method_three: function(arg=some_arg){ /*code for method three*/},
        });
        return BasicService;
    }   
);

Now i want to define an Extended service that extends from the above BasicService so that i can use methods defined under the BasicService from my extended service. Maybe something like:

    factory('ExtendedService', function($http){
        var ExtendedService = BasicService();
        ExtendedService['method_four'] = function(){/* code for method four */}
        return ExtendedService;
    }
like image 344
Amyth Avatar asked Mar 08 '13 12:03

Amyth


5 Answers

More cleaner and imperative way

.factory('ExtendedService', function($http, BasicService){

    var extended = angular.extend(BasicService, {})
    extended.method = function() {
        // ...
    }
    return extended;
}
like image 146
S.C. Avatar answered Nov 20 '22 01:11

S.C.


Your ExtendedServiceshould inject the BasicServicein order to be able to access it. Beside that BasicService is an object literal, so you can't actually call it as function (BasicService()).

.factory('ExtendedService', function($http, BasicService){
  BasicService['method_four'] = function(){};
  return BasicService;
}
like image 26
Stewie Avatar answered Nov 20 '22 02:11

Stewie


In my opinion, a better way:

.factory('ExtendedService', function($http, BasicService){
    var service = angular.copy(BasicService);

    service.methodFour = function(){
        //code for method four
    };

    return service;
});

Here at least does not change the inherited service.

like image 18
Vitaly Sivkov Avatar answered Nov 20 '22 00:11

Vitaly Sivkov


Sorry if I post here but may be it's a good place to do it. I refer to this post

watch out to extend a service/factory because are singleton so you can extend a service/factory once.

'use strict';
            angular.module('animal', [])
                .factory('Animal',function(){
                        return {
                            vocalization:'',
                            vocalize : function () {
                                console.log('vocalize: ' + this.vocalization);
                            }
                        }

                });
                angular.module('dog', ['animal'])
                    .factory('Dog', function (Animal) {
                        Animal.vocalization = 'bark bark!';
                        Animal.color = 'red';
                        return Animal;
                    });

                angular.module('cat', ['animal'])
                   .factory('Cat', function (Animal) {
                        Animal.vocalization = 'meowwww';
                        Animal.color = 'white';
                        return Animal;
                    });
                 angular.module('app', ['dog','cat'])
                .controller('MainCtrl',function($scope,Cat,Dog){
                     $scope.cat = Cat;
                     $scope.dog = Dog;
                     console.log($scope.cat);
                     console.log($scope.dog);
                    //$scope.cat = Cat;
                });

but if you do like

'use strict';
            angular.module('animal', [])
                .factory('Animal',function(){
                    return function(vocalization){
                        return {
                            vocalization:vocalization,
                            vocalize : function () {
                                console.log('vocalize: ' + this.vocalization);
                            }
                        }
                    }
                });    
                angular.module('app', ['animal'])
                    .factory('Dog', function (Animal) {
                        function ngDog(){
                            this.prop = 'my prop 1';
                            this.myMethod = function(){
                                console.log('test 1');
                            }
                        }
                        return angular.extend(Animal('bark bark!'), new ngDog());
                    })
                    .factory('Cat', function (Animal) {
                        function ngCat(){
                            this.prop = 'my prop 2';
                            this.myMethod = function(){
                                console.log('test 2');
                            }
                        }
                        return angular.extend(Animal('meooow'), new ngCat());
                    })
                .controller('MainCtrl',function($scope,Cat,Dog){
                     $scope.cat = Cat;
                     $scope.dog = Dog;
                     console.log($scope.cat);
                     console.log($scope.dog);
                    //$scope.cat = Cat;
                });

it works

like image 3
Whisher Avatar answered Nov 20 '22 00:11

Whisher


I wrote an $extend provider that uses Backbone's extend under the hood -- So you get both prototype and static property extending in case you need them -- Plus you get parent/child constructors -- see gist @ https://gist.github.com/asafebgi/5fabc708356ea4271f51

like image 1
a5af Avatar answered Nov 20 '22 02:11

a5af