Dependency Injection and Minification

Anthony Alicea
A free video tutorial from Anthony Alicea
Software Developer, Architect, and UX Designer
4.6 instructor rating • 8 courses • 278,048 students

Lecture description

AngularJS controllers need to survive minification. Here's how AngularJS accomplishes that.

This lecture contains downloadable source code. Download the file below and unzip (or extract) it.

Learn more from the full course

Learn and Understand AngularJS

Master AngularJS and the Javascript concepts behind it, design custom directives, and build a single page application.

06:51:33 of on-demand video • Updated September 2020

  • Learn fundamental Javascript concepts that power AngularJS.
  • Write quicker, better AngularJS code by discovering how AngularJS itself is built.
  • Become fluent in AngularJS terminology, such as dependency injection, services, directives, transclusion, and more.
  • Realize the power of dependency injection, and how AngularJS accomplishes it.
  • Design custom directives and save time and energy with easily reusable components.
  • Understand what a Single Page Application (SPA) is, and how they work.
  • Build a Single Page Application (SPA) in AngularJS.
  • Be the coder that explains AngularJS to everyone else, because you understand it better than anyone else.
  • Get new free lectures during 2015, keep up with the development of AngularJS 2.0, and get a MASSIVE discount on a future AngularJS 2.0 course in 2016!
English Up to this point, we've come to understand how AngularJS does dependency injection. But actually, that's one of two ways that AngularJS does dependency injection. The second involves dependency injection and minification of JavaScript files. Let's look at that. Okay, so you know what I'm gonna hit you with real quick. Just a quick reminder. Big word alert. Minification, break glass. Minification is the shrinking of the size of files for faster download. So I might have a big JS or a CSS file. We can minify it, make it smaller. So that it's smaller to download for the person and the app responds faster. We normally add .min to the name of the files. So, file.js becomes file.min.js, that we can tell the difference just when we're looking at the files. Okay, let's take a quick look. I'm back at my basic app and controller, and I have a couple of services that I'm injecting into my controller, scope and log, so we've seen this before. And let's suppose I'm going to log, actually let's do this, I'm going to log the scope. So let's run this. And we can see that there's the scope. Okay, so that works just fine. Now let's suppose I went to go and minify this JS file. Now this is something you should really do in a real world environment. These JS files contain lots of extra characters, spaces and returns. But a really good modifier does more than that. And that's where we get into a bit of trouble with AngularJS's Dependency Injection. I'm just gonna take this controller and go find a JavaScript minifier. Let's just search for a minifier, a JavaScript minifier. I'll just grab one of them and I am going to go ahead and drop my code, this controller into this minifier and then compress it. Let's see what we get out. Okay, here's the code that the JavaScript minifier gave me, it took this controller and turned it into this, see what it did? It removed all of my spaces, it removed the carriage returns. That makes the total download size smaller, less bits and bytes to download. But a really good minifier does something more. It takes variables and renames them to the smallest size it can, just one letter if it can. Because, that also can save a lot of space and download time. So, I've got this controller, instead of scope and log, it changed that to a,b and then b, which was log a which was scope. So normally that's great, but if I use this version of controller, what's going to happen? What do you think? Refresh it, boom, errors. Injector errors. It couldn't find this variable. Why? Well, remember how AngularJS does dependency injection. It looks at the list of perimeters as a string and tries to find the certain name. So, when the minifier changed the name of the variable, it broke AngularJS's dependency injection. So what do we do about that? Well, the folks that wrote AngularJS already thought about this. And they provided us a second method for specifying dependency injection. Just for the case of JavaScript that's going to be minified. Now since you definitely should be minifying your JavaScript when you push applications out in the real world. From this point forward in the course we're always going to use the method that I'm about to show you, and this is probably the method that you should get used to using. We wanted to first use the simple method to explain dependency injection. But now, we're going to show you the other way. So, let me put back my controller. Get rid of that minified one that broke. Now I should refresh, yeah, and I see the scope is being logged. Now this controller method takes a string and a function. The name of the controller and the code along with it, but there's a second option for when I pass something to the controller. I can pass an array. So I'll start by wrapping this function in brackets. See that brackets means this is an array and I'll add some elements. Other elements to the array and that's it. So, what just happened? Remember that a JavaScript array can contain many types of things including functions themselves. So this array being passed to the controller contains two strings and a function. And you'll see that the way the controller ends looks a little funky, you have to get that right, you're finishing the function, then you're finishing the array, then you're finishing the controller. The last element of the array is always the function that defines the controller. And the elements of the array that come before should be whatever parameters are supposed to get passed to the controller. Through the function. Let's see why this works. Let's go back to our minifier, so I'm going to minify this code instead. And I'll compress it. Let's grab it and take a look. Well it did the same thing. It removed all the spaces and unnecessary carriage returns. And it did rename these variables, scope and log, to A and B. But do you see what didn't change? Those first two elements of the array. Why? Because a minifier is never going to change the values inside a string. It's never gonna touch what's between two quotes, because that's something that you're explicitly specifying in the code. So since it won't change the value of variables just the names of variables, it keep these values the same. This version of the AngularJS dependency injector then says well I see an array, so instead of looking at the function, I'm going to look at the first elements of the array, and then I'll look at that name and determine what object is expected. And I'll pass it to that position in the function. So it looks at the last element of the array, and says there's my function. It says okay the first element of the array, will be the first parameter. The second element of the array, I'll pass as the second parameter, and so and so forth. So I could keep adding, if I had them available to me. And I would just have more variables perhaps than the minifier would create. So I can have as many parameters, and the function is always last And it'll match them up. So if I try this controller, this minify controller, I should still get and I do. My scope was injected properly at this position. Now that does mean there's a bit of a difference, between how this works and how the first version of the dependency injector worked. Well first of all this is great, right? We can minify our JavaScript and it still works. If I go back to my un-minified version, because Angular JS is no longer looking at the function and reading it and deciding What goes where. If I swap these But don't swap them here. What do you think's gonna happen? Well, let's take a look. Boom. It's broken. Why? Well, let's just take a look at what's in my scope, this second parameter. Wait a minute. That's the log object. Why? Well again, because this version of the angular JS Dependency injector doesn't look at what the names are in the parameter list in the function itself. It looks at these elements of the array and matches them to the position. So in this version. The order matters. I told angular the first element should get the scope, and the second parameter should get the log, and it doesn't matter what I name these. I could name these a and b. And b is going to be the log, see? Because of that you have to be very carefull. If I were to swap this order, I need to swap that order. This will pass to the first parameter and this will pass to the second parameter and so on and so forth, no matter the name. So even though it looks the same as the first version, order really does matter. And that's the key, that's the thing to remember, if you ever find yourself accidentally having this be the wrong order, make sure that your parameters as your first elements of the array. Appear in the same order that they appear when you define the function and beyond that you now have a controller definition that will survive minification. This is the way we're going to define controllers for the rest of the course. So, you probably wanna get used to trying this, get used to how looks, get used to passing the array. passing some parameters creating a function, finishing that whole section of code out properly with your curly brace, your bracket and then your parentheses. Once you're used to that, it's actually pretty easy. So, when you first might see this, this might look really confusing but now, we can see that its just a matter og using JavaScript arrays, and the power of those in order to survive minification. So, that's dependency injection and minification in AngularJS.