6

I have normally learned that function implementation can have any name for function arguments as long as it is supplied in the right order. This makes the function abstracted from the outside world and the local names have no effect on the output . Implementer has all the rights for local variables. However in Angular JS, it seems to counter intuitive to have something like:

function Controller($scope)
{
    $scope.name = "Something";
}

If I put "bar" there instead "$scope" I get an error. This is not the normal function that we are used to . I believe it something to do with DI, but can anyone explain this concept ? I find it hard to call this a "function" because it is dependent on the outside world - especially the argument name .

If DI is the real reason , can any one let me know how does it get invoked ? Normally I can think of DI doing good when I want to mock an object for test case. In this case what role does DI play ?

In the normal scenarios of DI that I have come across , the argument that gets passed, does a service for the function like say foo displayTime(clock) { clock.something } . Time is just a service for the the function . However here I find that , the $scope and the framework seems to do the magic with the function just being declarative way of expressing the logic .

Edit : Apparently JS minify breaks this functionality and we need to do like in How do the function argument names in Angular.js objects connect to other objects?

2
  • 2
    Angular actually evaluates the arguments (using Function.toString ) names and injects the right resource, this is one of the baffling things you learn when you get started with angular ! see here: stackoverflow.com/questions/16949889/… Commented May 22, 2014 at 13:09
  • 1
    "In normal scenarios of DI I have come across , the argument that gets passed does a service for the function"... This is also the case in Angular, scopes are however a little special... github.com/angular/angular.js/wiki/Understanding-Scopes which goes into details about scopes and docs.angularjs.org/guide/scope which probably sticks more to how you should use them But you may just as well inject your own clock service defined as: myApp.service('clock', ['otherDependency', function(od) { this.something = "Im a clock!"; }]); Commented May 22, 2014 at 13:28

1 Answer 1

7

One way to define a controller is like so:

myApp.controller("TestController", ['$scope', function(bar) {
   // now "bar" is actually the scope variable
}]);

The whole reason that angular works like this is because of the way it does dependency injection. Basically it looks for the dependancies (eg $scope) and it tries to inject them based on name of the variable. That means if you name $scope something different then it tries to inject that other item instead. bar isn't something that angular knows how to inject so you are going to get an undefined value instead of the $scope you were expecting.

My example above works because I used an array to separate out the names of the variables that are going to be injected from the variables themselves. Now you don't have to use the word $scope but you must keep the variables in the same order. The whole concept of DI is too complicated to explain in a short post so I recommend reading more about it on angular's site here: https://docs.angularjs.org/tutorial/step_05

The Point of DI (in angular)

In case you are wondering - why go to all this trouble? Why not just automatically inject $scope into the first variable that you have in the list? The answer is - flexibility & customization. With angular, you can define your services and factories, then inject them into your controllers. This gives you the power to define shared routines, objects or even custom controls and then use them across as many controllers as you want. Without DI - none of this would be possible. Again, these are pretty complicated concepts so I recommend starting with a leap of faith that "it works", learning about services, then later you can go back and read more about it. At that point I think DI should make a whole lot more sense!

Best of luck!

Sign up to request clarification or add additional context in comments.

9 Comments

Interesting . So basically you mean the function is mean to be called by Angular and not outside world ? Its not purely a JS function ?
@Nishant You can call the function as you defined it from anything, but it obviously won't be doing you much good. Regardless, you should use the syntax drew_w provides here as it also means you can safely minify your code without breaking the functionality.
@Nishant It uses DI to inject variables, but it is still a pure javascript function. I recommend reading more about DI to understand what is going on here!
Yes I mean the DI has special purpose for Angular framework . Right I would check into DI concept .
@Nishant Angular uses it's injector ($injector) for most instantiations and calls to functions you defined in an angular application... The injector is an IoC container. DI it self doesn't do anything of all this as it just specifies a concept for providing an object/service with what it needs from the outside. The IoC container means you can automate the whole creation process. So you should probably also read a little up on IoC containers. In JavaScript we can't resolve things by "Type" or "Interface", so instead we use names.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.