4

I am trying to find of a way to extend services in angular. I am not sure if angular has a concept of extending or if it merely relies on injection for code reuse. So what I have tried so far are the following

Method 1

myApp.factory('myFactory', function ($http) {
   return{
     common: function(){
      console.log('I am from myFactory');
     }
});


 myApp.factory('myFactory1', function (myFactory) {
    return {
     common: myFactory.common
    };
});

OR

 myApp.factory('myFactory1', function (myFactory) {
    return angular.extend(myFactory, {
     common: function() {
      console.log('I am form Factory1')
      }
    });
});

Both approaches sort of work OK but my main issue is how to call the parent. i.e. something like this:

in myFactory1

     common: function(){
      console.log('I am from myFactory1');
      this.prototype.common.apply(this, arguments);
     }

I want is to print out 'I am from myFactory1', 'I am from myFactory'

Generally Is this supported in angular ? Or should I take a different approach in extending /inheriting functionality?

Thank you

2
  • if it meets your requirements go ahead. angularjs services are singletons. So you should favorise composition over inheritance. Commented May 21, 2014 at 16:19
  • So can't call parent function with same name? Commented May 21, 2014 at 16:24

2 Answers 2

4

The way I've achieved this in the past is to have the base angular service return an instance of a plain old Javascript 'class'. The extended service, then creates an instance of the base class, and uses standard JS prototypal inheritance to extend the class and returns an instance of the new extended object.

For example:

// Base service
app.factory('Shape', function() {

    var Shape = function(colour) {
        this.colour = colour;
    };

    Shape.prototype.getColour = function() {
        return this.colour;
    };

    return Shape;
});

// Extended service
app.factory('Square', function(Shape) {

    var Square = function(colour) {
        Shape.apply(this, arguments);
    };

    Square.prototype = new Shape();

    Square.prototype.getSides = function() {
        return 4;
    };

    return Square;
});
Sign up to request clarification or add additional context in comments.

1 Comment

The code as you have it will cause Shape's constructor to get called an extra time when Square is defined. I would suggest that Square.prototype should be defined like: Square.prototype = Object.extend(Shape.prototype); Note that Object.extend is not present on all browsers, but es5-shim has a shim for it.
0

Just a few tweaks on Square @romiem snippet:

// Extended service
app.factory('Square', function(Shape) {

    var Square = function(colour) {
        Shape.call(this, arguments);
    };

    Square.prototype = Object.create(Shape.prototype);
    Square.prototype.constructor = Square;

    Square.prototype.getSides = getSides;

    return Square;

    function getSides() {
      return 4;
    }

});

This snippet follows best practices and avoid the problem about create a new instance through new Shape(). Also in compatible with old browsers.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.