How to avoid a large number of dependencies in Angularjs

All we need is an easy explanation of the problem, so here it is.

I have an Angular application. Its working good, but as my application is getting bigger I’m worried about the large number of dependencies that I have to inject in each controller.

for example

app.controller('viewapps',[
    '$scope','Appfactory','Menu','$timeout','filterFilter','Notice', '$routeParams', 
    function($scope,Appfactory,Menu,$timeout,filterFilter,Notice,$routeParams) {
        //controller code..    
}])

I am sure that the list of dependencies are going to increase in future. Am I doing something wrong here? Is this the right approach? What is the best way to effectively handle this?

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

It’s hard to be specific without an exact use case, or seeing the exact code in your controller, but it looks like your controller might be doing too much (or might end up doing too much as you add things later). 3 things you can do:

  • Delegate more of the logic to service(s) that are injected in.

  • Separate out into different controllers, so each only has (just about) 1 responsibility.

  • Separate out into directives, each with their own controllers and templates, and allow options to be passed in, and output given out, via attributes and the scope option of the directive. This is often my preferred option, as you end up building a suite of reusable components, each with a mini-API.

    It is fine for directives to be used like this, at least in my opinion. They aren’t just for handling raw Javascript events, or accessing the DOM directly.

Method 2

I’ve been playing with the idea of bundling services based on controllers.

So in your example you’d refactor your; AppFactory, Menu, filterFilter and Notice services into a single service e.g. ViewAppsServices.

Then you’d use your services like ViewAppsServices.AppFactory.yourFunction().

As I see it that way you can at least shift your injections into another file cleaning your controller up a bit.

I think readability would suffer a bit since another developer would then have to look at bundles rather than the controller itself.

Here’s a JSFiddle I put together to demonstrate how it would work; this is how I’d imagine yours would work.

.service('ViewAppsServices', ['AppFactory', 'Menu', 'filterFilter', 'Notice', 
function (AppFactory, Menu, filterFilter, Notice) {
    return {
        AppFactory: AppFactory,
        Menu: Menu,
        filterFilter: filterFilter,
        Notice: Notice
    };
} ])

Method 3

Try to move as much logic as possible to services, even just make controller methods act as “routing – passing through” methods . After time you will see it very usefull if you will want to use similar methods in other controllers/directives. Anyway, 7 injections is in my opinion not much 🙂

(edit: see the comment of Matt Way below)
Also, a tip – in newer versions of Angular you don’t have to write this array, just:

app.controller('viewapps', function($scope,Appfactory,Menu, $timeout,filterFilter,Notice,$routeParams){
   //controller code..    
}])

Method 4

My approach is to use $injector, when there are lots of dependencies:

app.controller('viewapps', ['$scope','$injector',function($scope,$injector){                               
    var Appfactory = $injector.get('Appfactory');
    var Menu = $injector.get('Menu'); 
    //etc...
}]);

The advantages:

  • Code can be minified and obfuscated safely
  • You don’t need to count the index of the dependency, when you declare dependency as a function’s parameter

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply