{"id":16,"date":"2015-02-16T19:39:00","date_gmt":"2015-02-16T19:39:00","guid":{"rendered":""},"modified":"2016-01-30T23:18:53","modified_gmt":"2016-01-30T23:18:53","slug":"angularjs-dependency-injection","status":"publish","type":"post","link":"https:\/\/tpodolak.com\/blog\/2015\/02\/16\/angularjs-dependency-injection\/","title":{"rendered":"AngularJS &#8211; dependency injection"},"content":{"rendered":"<p>There are couple of ways of injecting dependencies into AngularJS components. The most common one is just to specify the dependency name in the function&#8217;s argument list<\/p>\n<pre lang=\"javascript\">\r\n(function() {\r\n    angular\r\n        .module('app')\r\n        .controller('shellCtrl', function ($scope, $http) {\r\n            $scope.title = \"Title\";\r\n        });\r\n})();\r\n<\/pre>\n<p>However this technique fails in real life scenarios, because for production we usually (or rather always) minify and uglify javascript files. Uglify proces renames our variables and due to the fact that dependencies are resolved by name, AngularJS is not able to find appropriate services, directives etc. To overcome this limitation, we can enclose our function definition into an array, and specify dependencies as a string literals. Our original code becomes then<\/p>\n<pre lang=\"javascript\">\r\n(function () {\r\n    angular.module('app')\r\n           .controller('shellCtrl', ['$scope', '$http', function ($scope, $http) {\r\n               $scope.title = \"Title\";\r\n           }]);\r\n})();\r\n<\/pre>\n<p>Although this works fine even after minifying and uglifiyng js files, for me this code is hard to read. That is why I like to use yet another technique. This technique leverages variable hoisting and <i>$inject<\/i> property<\/p>\n<pre lang=\"javascript\">\r\n(function(){\r\n    angular.module('app')\r\n           .controller('shellCtrl',shellController);\r\n\r\n    shellController.$inject=['$scope','$http'];\r\n\r\n    function shellController($scope,$http){\r\n        $scope.title='title';\r\n    }\r\n})();\r\n<\/pre>\n<p>As You can see I extracted controller function into separate variable &#8220;shellController&#8221; and listed all necessary dependencies in <i>$inject<\/i> array<\/p>\n<pre lang=\"javascript\">\r\nshellController.$inject= ['$scope','$http']\r\n<\/pre>\n<p>It is even possible to enhance a bit this example and make it a little less error prone. With the current implementation we have to make sure that order of properties in <i>$inject<\/i> array is the same as in function declaration. It is easy to keep track of that if we have just a couple of dependencies, but it might be a bit of a pain if we start to add, remove or edit them. Fortunately we can automate this task and basically autogenerate <i>$inject<\/i> array. In order to do that I like to use Gulp (although it is also possible to use Grunt). First of all we have to install Gulp. There is great tutorial how to do that in here https:\/\/github.com\/gulpjs\/gulp\/blob\/master\/docs\/getting-started.md Having Gulp on board we have to install additional packages: <i>gulp-rename<\/i> and <i>gulp-ng-annotate<\/i>. In order to do that type into command line<\/p>\n<pre lang=\"bash\">\r\nnpm install gulp-ng-annotate --save-dev\r\nnpm install gulp-rename --save-dev\r\n<\/pre>\n<p>Now we can create gulp.js file which should look more or less like that<\/p>\n<pre lang=\"javascript\">\r\nvar rename = require('gulp-rename'),\r\n    ngAnnotate = require('gulp-ng-annotate');\r\n\r\ngulp.task('annotate', function () { \/\/create new task 'annotate'\r\n    return gulp.src('app\/layout\/controllers\/shellController.js') \/\/select files to process\r\n        .pipe(ngAnnotate()) \/\/ add angularjs dependeny injection annotation\r\n        .pipe(rename('app.all.js')) \/\/rename in-memory stream to app.all.js\r\n        .pipe(gulp.dest('.build'));\/\/save stream to new location\r\n})\r\n<\/pre>\n<p>We can run this task typing into command line<\/p>\n<pre lang=\"bash\">\r\ngulp annotate\r\n<\/pre>\n<p><a href=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2015\/02\/angularjs-extending-existing-services-using-decorator\/gulp.png\" rel=\"attachment wp-att-276\"><img decoding=\"async\" src=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2015\/02\/angularjs-extending-existing-services-using-decorator\/gulp-1024x213.png\" alt=\"gulp dependency injection\" width=\"800\"  class=\"aligncenter size-large wp-image-276\" srcset=\"https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2015\/02\/angularjs-extending-existing-services-using-decorator\/gulp.png 1024w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2015\/02\/angularjs-extending-existing-services-using-decorator\/gulp-150x31.png 150w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2015\/02\/angularjs-extending-existing-services-using-decorator\/gulp-300x62.png 300w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><br \/>\nAnd as a result our original code (notice lack of dependeny annotations &#8211; no $inject arrray)<\/p>\n<pre lang=\"javascript\">\r\n(function() {\r\n    angular.module('app')\r\n           .controller('shellCtrl', shellController);\r\n\r\n    function shellController($scope, $http) {\r\n        $scope.title = 'title';\r\n    }\r\n})();\r\n<\/pre>\n<p>Will be transformed into<\/p>\n<pre lang=\"javascript\">\r\n(function(){\r\n    angular.module('app')\r\n           .controller('shellCtrl',shellController);\r\n\r\n    function shellController($scope,$http){\r\n    }\r\n    \r\nshellController.$inject=[\"$scope\",\"$http\"];\r\n})();\r\n\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>There are couple of ways of injecting dependencies into AngularJS components. The most common one is just to specify the dependency name in the function&#8217;s argument list (function() { angular .module(&#8216;app&#8217;) .controller(&#8216;shellCtrl&#8217;, function ($scope, $http) { $scope.title = &#8220;Title&#8221;; }); })(); However this technique fails in real life scenarios, because for production we usually (or [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[28,13,18],"tags":[178,168,174],"class_list":["post-16","post","type-post","status-publish","format-standard","hentry","category-angularjs","category-gulp","category-javascript","tag-angularjs","tag-gulp","tag-javascript"],"_links":{"self":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts\/16","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/comments?post=16"}],"version-history":[{"count":5,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts\/16\/revisions"}],"predecessor-version":[{"id":529,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts\/16\/revisions\/529"}],"wp:attachment":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/media?parent=16"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/categories?post=16"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/tags?post=16"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}