AngularJS Inheritance Patterns

Since AngularJS does not provide any built-in features for using inheritance, in this blog post I’ll describe how the general JavaScript inheritance patterns can be applied to AngularJS components.

Controllers inheritance

First, lets talk about controllers. Actually it is very unlikely to inherit from parent controller. This is the case because by implementation the scope in the child controller will inherit prototypically from the scope of its parent. So when you need to reuse functionality from the parent controller, all you need to do is add the required methods to the parent scope. By doing this the child controller will have access to all these methods through the prototype of its scope i.e.:

Of course, the inheritance creates very strong coupling but only in single direction (i.e. the child is strongly coupled to its parent), so you can’t directly call children methods from your parent controller. For doing this you need to use event dispatching:

I’m providing this snippet only informative, if you need to call children methods from your parent controller there might be something wrong in your code.

OK, but now let’s imagine you have two pages with almost the same functionality, lets say the intersection between the functionality of the pages is more than 50%. They might have totally different views but the logic behind these views could be quite similar. In such case you can create a base controller which to encapsulate the common logic, and two children controllers which to inherit from it. The base controller is not necessary to be implemented as AngularJS controller component you can use simple constructor function:

Now the children controllers can easily inherit from the base controller by:

As you see we directly apply the “Klassical” inheritance pattern. We can do the same for the second child controller. You can check example right here.

Services inheritance

As you know there are two ways to create injectable (through DI) AngularJS services:

  • module.factory(name, factoryFn)
  • module.service(name, factoryFn)

module.factory

In module.factory the factoryFn returns object literal which is the actual service. Behind the scene AngularJS calls the factory function called inside the injector definition

If you need inheritance between services which are instantiated through module.factory the prototype inheritance pattern through Object.create fits just great!

Lets create the base service:

and here is the child service:

Now you can inject ChildService in different component and reuse the inherited from BaseService functionality.

You can check example right here.

Inject the parent

One more pattern for inheritance with services is injecting the parent through dependency injection and creating new object, which inherits from the parent prototypically:

This pattern is definitely much more useful when you need to inject some dependencies to the parent service.

module.service

Usually I call the variables attached to my scope View Models and some special services – Models. I implement these services with something close to the Active Record Pattern. My models are usually responsible for talking to the server, sometimes directly but usually through a Gateway. For the creation of these models I prefer to use module.service method. Internally these services are created through the instantiate method.

Why I prefer using service instead of factory? Well, may be I’m a confused developer who don’t understand the true power of the prototypal inheritance used with pure object literals but I prefer to use the classical style for my models. By using it I can create a set of constructor functions which model my domain pretty well. Who knows for large project I may decide to use MDD and generate all my models from some fancy UML diagrams…

Here is an example of how you can take advantage of the Klassical inheritance pattern for AngularJS services created with module.service:

You can check this related exercise from ng-tutorial.

7 thoughts on “AngularJS Inheritance Patterns”

  1. The case you described, having 1 base controller with 2 child controller who share more than 50% of the logic, has happened to me a couple of times, and I kind of had a clue that something C#, JS pseudo-inheritance like could be done but didn’t do it because I was in a rush but now that some maintenance needs to be done the inheritance approach comes really handy.

    Thank you, great post!

    1. Thanks! You can inject dependencies the same way:

        1. You can use $injector and get the dependencies using annotate. After that with $injector.get(name:String) you can get the individual dependency instances and pass them to BaseService.

          I’ll post one more pattern which will make the process easier.

          1. I’ve played with that new pattern a bit, added some properties and overloading and it seems to be working nicely.
            Thank you!

  2. Thank you for posting, always need more people sharing knowledge. With regards to the “two controllers sharing 50% logic”, just one thing to note. I realize this post was about inheritance, but it should be mentioned (as a side note?) that the angular way would have been to create a service for those controllers. This would have also kept things off of window. Just wanted to add that for anyone googling by:)

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">