{
    "componentChunkName": "component---src-templates-post-js",
    "path": "/blog/2013/08/18/configuring-dependency-injection-in-angularjs",
    "result": {"data":{"site":{"siteMetadata":{"title":"your friend Joel's digital garden","description":"Articles and notes from a collaborator at egghead.io. Musings on software, business, and life from a skilled virtual assistant.","author":{"name":"Joel Hooks"},"keywords":["Video Blogger"]}},"mdx":{"excerpt":"Dependency injection is the act of supplying values or object instances (dependencies) to target objects\nfrom outside of the target object. In many (most?) cases this is automated\nby a framework, such as AngularJS. This means that a given…","fields":{"github":"https://github.com/joelhooks/joelhooks-com/tree/master/content/legacy_blog/2013-08-18-configuring-dependency-injection-in-angularjs.markdown"},"body":"var _excluded = [\"components\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"layout\": \"post\",\n  \"title\": \"Configuring Dependency Injection in AngularJS\",\n  \"date\": \"2013-08-18T00:00:00.000Z\"\n};\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, _excluded);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"Dependency injection is the act of supplying values or object instances (dependencies) to target objects\\nfrom outside of the target object. In many (most?) cases this is automated\\nby a framework, such as AngularJS.\"), mdx(\"p\", null, \"This means that a given target object does \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"not\"), \" create its own dependencies,\\nthrough the use of the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"new\"), \" keyword or other creation methods.\"), mdx(\"p\", null, \"By creating and managing dependencies\\noutside of an object, it makes it much easier to switch out that dependency as\\nneeded. This is very useful when you are writing your unit tests, and can have\\nmany advantages in larger systems.\"), mdx(\"p\", null, \"There are only three ways for an object to resolve its dependencies:\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"internally, via the \", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"new\"), \" operator\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"lookup via a global variable (requirejs is an example)\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"the dependency is passed to the object\")), mdx(\"p\", null, \"The third option is \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"dependency injection\"), \", and it is the preferred approach in\\nAngularJS apps.\"), mdx(\"h2\", null, \"Defining your dependencies\"), mdx(\"p\", null, \"Dependency injection is a core feature of AngularJS. There are 3 approaches to\\ndefining your dependencies, ordered by complexity from least to most:\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"module.service\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"module.factory\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"module.provider\")), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"note:\"), \" \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"AngularJS also provides \", mdx(\"inlineCode\", {\n    parentName: \"em\"\n  }, \"value\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"em\"\n  }, \"constant\"), \" dependencies. We aren't\\ngoing to get into those two today.\")), mdx(\"p\", null, \"Both \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"service\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"factory\"), \" are abstractions that sit on top of \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"provider\"), \".\\nUsing \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"factory\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"provider\"), \" will give you more flexibility, but are more\\nverbose.\"), mdx(\"p\", null, \"Before we look at how to use these tools, let's take a look at the AngularJS\\nsource code and understand how they work.\"), mdx(\"h3\", null, \"Interlude into the AngularJS internals\"), mdx(\"p\", null, \"If you're a geek like me, you might be curious as to what is going on under the hood\\nwhen you declare dependencies.\"), mdx(\"p\", null, \"I mentioned earlier that \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"service\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"factory\"), \" were abstractions on top of \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"provider\"), \".\\nTo show you exactly how that works, we need to open up \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"injector.js\"), \" in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"src/auto/\"), \"\\nfolder in the AngularJS source code:\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-javascript\"\n  }, \"function provider(name, provider_) {\\n  if (isFunction(provider_) || isArray(provider_)) {\\n    provider_ = providerInjector.instantiate(provider_);\\n  }\\n  if (!provider_.$get) {\\n    throw $injectorMinErr(\\n      'pget',\\n      \\\"Provider '{0}' must define $get factory method.\\\",\\n      name,\\n    );\\n  }\\n  return (providerCache[name + providerSuffix] = provider_);\\n}\\n\\nfunction factory(name, factoryFn) {\\n  return provider(name, { $get: factoryFn });\\n}\\n\\nfunction service(name, constructor) {\\n  return factory(name, [\\n    '$injector',\\n    function($injector) {\\n      return $injector.instantiate(constructor);\\n    },\\n  ]);\\n}\\n\")), mdx(\"p\", null, \"As you can see at a glance, \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"service\"), \" calls \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"factory\"), \" which calls \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"provider\"), \". So, when it\\ngets right down to it, these three methods are the exact same thing. Convenient!\"), mdx(\"p\", null, \"Almost the exact same thing.\"), mdx(\"p\", null, \"There is a subtle difference. The AngularJS \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"service\"), \" uses\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"$injector.instantiate\"), \" on the constructor function that you pass in. This means\\nthat internally the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"service\"), \" creates an instance of your function with the\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"new\"), \" operator. This will provide the resulting object a valid 'this' scope.\"), mdx(\"p\", null, \"Using \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"strong\"\n  }, \"factory\"), \" doesn't call \", mdx(\"inlineCode\", {\n    parentName: \"strong\"\n  }, \"new\"), \" on the function that is passed in\"), \".\\nWhen using \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"factory\"), \", the function that is passed in is called directly, and an\\nobject is expteded to be returned.\"), mdx(\"p\", null, \"Hat tip to\\n\", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://twitter.com/ThomasBurleson\"\n  }, \"@ThomasBurleson\"), \" for pointing this\\nout. This can be confusing if encountered in the wild. Now you know.\\nHalf the battle.\"), mdx(\"p\", null, \"Let's start with the simplest use case. The \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"service\"), \".\"), mdx(\"h3\", null, \"Defining a service in AngularJS\"), mdx(\"p\", null, \"A service instantiates a constructor function.\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-javascript\"\n  }, \"(function(angular) {\\n  var module = angular.module('myApp.myModel', []);\\n\\n  var MyModel = function MyModel(asyncService) {\\n    return {\\n      someApi: function() {\\n        return asyncService.getStuff();\\n      },\\n    };\\n  };\\n\\n  module.service('myModel', ['asyncService', MyModel]); //simple option\\n})(angular);\\n\")), mdx(\"p\", null, \"In this example we are creating a module that will store a model that grabs data from some asynchronous\\nservice. The \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"myModel\"), \" service will return an instance of \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"MyModel\"), \" when it is requested\\nfor injection by other objects. The instance of \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"MyModel\"), \" is a singleton, and only one instance will\\never be created and used by the application.\"), mdx(\"p\", null, \"This example could actually be even simpler if the injectable doesn't require any additional\\ndependencies.\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-javascript\"\n  }, \"module.service('myModel', MyModel); //most simple option\\n\")), mdx(\"p\", null, mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"module.service\"), \" requires only two arguments. A string for its unique name, and a constructor\\nto create an instance of. This approach is useful, and most of the time is probably all you need\\nfor your application.\"), mdx(\"p\", null, \"When you need more flexibility than the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"service\"), \" provides, it is time to look at \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"factory\"), \".\"), mdx(\"h3\", null, \"Defining a factory in AngularJS\"), mdx(\"p\", null, \"A factory returns an object.\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-javascript\"\n  }, \"(function(angular) {\\n  var module = angular.module('myApp.myModel', []);\\n\\n  var MyModel = function MyModel(asyncService) {\\n    return {\\n      someApi: function() {\\n        return asyncService.getStuff(); //promise?\\n      },\\n    };\\n  };\\n\\n  module.factory('myModel', [\\n    'asyncService',\\n    function(asyncService) {\\n      //could do some stuff here\\n      return new MyModel(asyncService);\\n    },\\n  ]);\\n})(angular);\\n\")), mdx(\"p\", null, \"Using a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"factory\"), \" provides additional flexibility. By providing a factory function\\nover a straight constructor, you are provided with the opportunity to do some work\\nprior to returning the object. You are also in charge of creating the\\ninstance that you want returned, unlike \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"service\"), \", which creates the\\ninstance for the constructor function you provide.\"), mdx(\"p\", null, \"The above example is obviously not\\ndoing anything interesting, but when you need to do some work prior to resolving a\\ndependency, a factory can be a good choice.\"), mdx(\"p\", null, \"In the real world, I've used \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"factory\"), \" to provide a configurable mock data \\\"mode\\\". The\\nfactory function would check to see which mode the app was in, and dynamically switch\\nbetween mock and real data. This can be incredibly handy when you want to work with out\\ndepending on external services.\"), mdx(\"p\", null, \"Note that the factory function will be called exactly \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"one time\"), \". Any work you do\\nwill only be done once, and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"myModel\"), \" will be whatever your factory function returns.\\nIn this case, we are simply returning an instance of \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"MyModel\"), \", but a factory can return\\nobjects \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"and\"), \" functions. Use that to your advantage.\"), mdx(\"p\", null, \"The last way to define dependencies is with \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"provider\"), \". Let's look at that next.\"), mdx(\"h3\", null, \"Defining a provider with AngularJS\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-javascript\"\n  }, \"(function(angular) {\\n\\n    var module = angular.module(\\\"myApp.myModel\\\", []);\\n\\n    var MyModel = function MyModel() {\\n        return {\\n            asyncService: null,\\n            someApi: function {\\n                return this.asyncService.getStuff(); //promise?\\n            }\\n        }\\n\\n    }\\n\\n    var myModelProvider = {\\n        model: new MyModel();\\n        $get: ['asyncService', function (asyncService) {\\n            this.model.asyncService = asyncService; //\\\"manual\\\" dependency injection\\n            return this.model; //resolved for the lifetime of app\\n        }]\\n    };\\n\\n    modules.provider('myModel', myModelProvider);\\n}(angular))\\n\")), mdx(\"p\", null, \"As you can see, \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"provider\"), \" is lower level. Explicit and verbose. The \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"$get\"), \" function\\nis used by AngularJS internally for the injector. A provider is \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"required\"), \" to have a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"$get\"), \"\\nfunction. When using \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"factory\"), \" (and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"service\"), \" as well) the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"$get\"), \" function is defined for\\nyou.\"), mdx(\"p\", null, \"For all practical purposes you will likely never need to use \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"provider\"), \" unless you are a\\ncontrol freak. In most circumstances a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"factory\"), \" or \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"service\"), \" will suffice, but it is nice\\nto know that \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"provider\"), \" is there, if you needed that level of explicit control for some reason.\"), mdx(\"p\", null, \"One thing to note about providers is that the provider is \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"available during \", mdx(\"strong\", {\n    parentName: \"em\"\n  }, \"configuration phase\"), \" of a module\"), \". While I haven't found a specific use case for this, it is something to have in your toolbox.\"), mdx(\"h3\", null, \"A little trick for dynamic dependencies\"), mdx(\"p\", null, \"I mentioned before that with a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"factory\"), \" (or \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"provider\"), \") you can return an object or a function.\\nAs it turns out, this can be very useful if you need to dynamically update a resolved dependency.\\nHere's a simple example using a factory.\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-javascript\"\n  }, \"module.factory('myDynamicInjectable', function() {\\n  var count = 0;\\n  return function() {\\n    count = count + 1;\\n    return count;\\n  };\\n});\\n\")), mdx(\"p\", null, \"This is an extremely trivial example, but now when you inject \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"myDynamicInjectable\"), \" and call it,\\nit will return the freshly incremented \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"count\"), \".\"), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"warning:\"), \" \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"don't do this. There are two things wrong with this example. It is storing state\\nwith the count variable, and then it is manipulating state. This isn't the appropriate location\\nfor either of those activities! A better solution would be to create an object that stored\\nthat state and provided a nice API for manipulating it.\")), mdx(\"p\", null, \"A more realistic (useful) use of this might look like this:\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-javascript\"\n  }, \"module.factory('getCurrentShoppingCart', [\\n  'getCurrentAccount',\\n  function(getCurrentAccount) {\\n    return function() {\\n      //getCurrentAccount is also a factory that returns a function\\n      //perhaps a user can have multiple accounts?\\n      return getCurrentAccount().shoppingCart;\\n    };\\n  },\\n]);\\n\")), mdx(\"p\", null, \"There is a ton of dynamic flexibility you can take advantage of when returning functions from\\nboth the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"provider\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"factory\"), \" approaches. I'd proceed with caution. You could easily abuse this\\nflexibility. Don't use this approach to manipulate and/or store state in the providers! The\\njob of these tools is to \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"resolve dependencies\"), \", and should be used only to \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"resolve dependencies\"), \".\"), mdx(\"h2\", null, \"Conclusion\"), mdx(\"p\", null, \"AngularJS provides several ways to configure dependency injection. From the simple \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"service\"), \" to the more flexible\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"factory\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"provider\"), \" approaches. You should have a solid understanding of how these work\\nunder the hood, and what situations are appropriate for each method.\"), mdx(\"p\", null, \"P.S. This article is the expansion of the answer to a question that was emailed to me.\\nIf you have any questions, I'd love to help you out. My email and twitter can be found below, and I\\nanswer them all.\"), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"Related:\")), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", {\n    parentName: \"li\",\n    \"href\": \"/blog/2013/05/01/when-is-a-singleton-not-a-singleton/\"\n  }, \"AngularJS, Dependency Injection, and When Is a Singleton Not a Singleton?\")), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", {\n    parentName: \"li\",\n    \"href\": \"/blog/2013/04/24/modeling-data-and-state-in-your-angularjs-application/\"\n  }, \"Modeling Data and State in Your AngularJS Application\"))));\n}\n;\nMDXContent.isMDXComponent = true;","frontmatter":{"title":"Configuring Dependency Injection in AngularJS","date":"August 18, 2013","banner":null,"slug":null,"keywords":null}}},"pageContext":{"id":"7a408dbc-c5e8-51bc-9c2a-c3ac1af91f00","prev":{"id":"3a853b3c-e6e3-5b1f-87e3-e5f288306c02","parent":{"name":"2013-09-15-why-i-built-an-angularjs-training-site-on-rails","sourceInstanceName":"legacy"},"excerpt":"If you're into AngularJS at all, you are probably familiar with the kickass  AngularJS video training  from egghead.io. If you haven't seen egghead.io, it is a collection of 50+ short \"bite-sized\" training videos, largely focused on the AngularJS…","fields":{"title":"Why I Built an AngularJS Training Site on Rails","slug":"blog/2013/09/15/why-i-built-an-angularjs-training-site-on-rails","date":"2013-09-15T00:00:00.000Z"}},"next":{"id":"5059a58c-5921-5c76-bdeb-745112675dee","parent":{"name":"2013-08-03-learn-angularjs-in-a-weekend","sourceInstanceName":"legacy"},"excerpt":"AngularJS has a reputation for a steep learning curve. It's definitely complex, but follows the 80/20 rule.  20% of the features are what you will use 80% of the time . If you are new to AngularJS and have a weekend to study, there are some very high…","fields":{"title":"Learn AngularJS this Weekend","slug":"blog/2013/08/03/learn-angularjs-in-a-weekend","date":"2013-08-03T00:00:00.000Z"}}}},
    "staticQueryHashes": ["1045846374"]}