[MUSIC] Now that we understand the idea of dependency injection, let's look at some code and delve a little deeper to understand how dependency injection can be implemented in JavaScript and in particular how it is implemented in AngularJS. Let's understand this magic that somehow allows Angular to figure out where to dynamically insert what type of object. In order to do that, we're going to build a small AngularJS application and explore a couple of special AngularJS services. Right now I'm located in Lecture09 folder, which is in the fullstack-course5/examples folder. And it's a very simple app. And so far, we've just instantiated and bound the app to this DIApp name. And we also have just one controller here, called DIController. And in it, we bound the name property of the scope, remember that scope, the glue between the view model and the view, which is our HTML. That scope, $scope, is going to have a property called name. So it's going to be completely bound. So let's go and take a look at our app.js. In our app.js, you could see that I am creating a module with the name DIApp, which is matching the ng-app attribute that I placed in my index.html. And I'm creating one controller, DIController. And the DIController, the function that's going to be responsible for that controller is called DIController. And what I'm passing here is the value of the function. And in the next line here, I'm going to define that function with the $scope. By the way, anything in Angular, pretty much anything in Angular with a dollar sign in front of it, not only does it belong to Angular, but it's also referred to as a service. So from now on, when I refer to $scope, I'm really going to just refer to the scope service. So as you can see, I'm defining a property on the scope service, and I'm giving it the string Yaakov. And of course, since this is bound to our index.html under model, the scope service is binding this property name, it automatically gets this Yaakov right inside of the text box. So what I would like to do next is create a functionality such that when the textbox loses focus like that, whatever is inside this textbox should get uppercased. And for that, I am going to introduce you to one more service called $filter. And we can inject it the same way we injected the $scope. So the filter service is a service that lets us create filtering functions that are used for formatting the data that eventually gets displayed to the user. So let's go ahead and create a function that our view will declaratively call when the text box loses the focus. So for now, we'll just go ahead and call it $scope. We need to put in on the scope service since we need to be able to expose it to our view. And we'll call it upper. And upper is a function, we don't need a name. Put a semicolon here. And the first thing we'll do is we'll create the uppercase function using the filter service. So we'll call it upCase, and that's the name of a function, and we'll call filter, and we'll just call it uppercase, that's the type of filter we want to get. And once we have that upCase function filter, we'll go ahead and say, $scope.name = upCase, so we're calling the function we just created, and we're passing it scope.name. So at this point scope.name would have been updated. So the only thing that's left is to go to index.html and go ahead and bind the ng-blur, which is when the textbox will lose focus. And we bind it to upper. And we'll call upper right here. And we'll go ahead and save it. So let's go ahead and see if it works. We'll go to our textbox right here, we'll type Coursera. We'll go ahead and click out of it. And as you can see, once we clicked out of it, the ng-blur which bound our upper function on our scope went ahead and called this upper function, which updated the name property of the scope service, which of course immediately got updated on our view. So the question still remains, how did Angular know that this is where the filter service should've been injected and this is where the scope service should've been injected? Well, let me go ahead and show you how that's done. First, what we're going to do is we're going to create just a completely irrelevant function to anything. We'll just call it function, and we'll call it AnnotateMe. And we'll give it, whatever, name, job, and blah parameters. And the function is going to be fairly simple. It's going to just return some string, let's call it Blah! Okay, so now we're returning string blah. And if we were to go ahead and console.log whatever blah returns. So we'll invoke the AnnotateMe function. And it doesn't matter what we pass, since we're not using any of those variables anyway. And we go ahead and save that. Let's go ahead and see what it's going to come out here. And it comes out blah. Okay, so that got invoked. But what happens if we don't invoke it? What happens if you just console.log just the actual function value? Let's go and save it. Look at that console output. It looks like it's just a string, which is the function definition itself. And if we actually do one better, we'll call toString on it. If we save that, we'll see that this is going to be just the string that represents the entire code of the function. Well, what does that mean? Well, one thing it means is that if we take that string and start parsing it, if we're smart enough here, we could go ahead and find the parentheses, find some string, find the comma, yet another string, comma. So what we could do is we could parse it. And the second one, see this name here, we could match this name with whatever services we have available and then instantiate those services, let's say we have a name service, and go ahead and call the AnnotateMe with that service, and we'll know that we need to inject it or we need to call AnnotateMe with a name service in position one as a argument. And we could exactly the same thing on this DIController. Let's go ahead and replace this with DIController. And when we save it, Browsersync updated our console here. Refresh the browser, and you see that the function DIController now is showing up in its full glory as just a regular string. So what Angular does is it can actually go ahead and parse out these names and find a matching service and then go ahead and instantiate those services and then call DIController with those instantiations. The service that does all this in Angular is called $inject. And we can actually even inject that service as well. So let's go ahead and do that and see what it can do. $injector, actually, I should say. So let's go ahead and maybe move this down here so it'll be a little bit easier to read. So what can this injector do? Well, we have this function called DIController, let's go ahead and console.log and have DIController. And instead of just logging DIController, what we're going to do is we're going to surround it with $injector.annotate. So if we call that. Let's go ahead and close this and save it. You'll see that our $injector.annotate gave us an array of the argument names to the function DIController. And this is exactly what Angular is using internally in order to figure out where to inject which services. And that's the magic, the magic has been revealed.