15

I asked a similar question earlier when attempting to inject $scope and $http into a controller Cannot call method 'jsonp' of undefined in Angular.js controller. Now I'm attempting to refactor that code slightly by moving the code into a function within the controller. I'm encountering similar issues and can't seem to grasp the mechanics of dependency injection in Angular. Below is my new code. Both $scope and $http are undefined. What I'm attempting to do is make an http request when didSelectLanguage() fires and assign the resulting data to the "image" variable in the $scope from the parent controller. Can someone enlighten me as to how dependency injection is supposed to work in this example?

angular.module('myApp.controllers', []).

  controller('ImagesCtrl', ['$scope', '$http', function ($scope, $http) {



        $scope.didSelectLanguage=function($scope, $http) {
            console.log($scope);
            $http.jsonp('http://localhost:3000/image?quantity=1&language='+this.language+'&Flag=&callback=JSON_CALLBACK')
            .success(function(data){
            $scope.image = data;
            });

        }

  }])
Community
  • 1
  • 1
hughesdan
  • 3,019
  • 12
  • 57
  • 80
  • 4
    This isn't the immediate answer to your question, but the article I wrote at [What “things” can be injected into others in Angular.js?](http://stackoverflow.com/questions/16828287/what-things-can-be-injected-into-others-in-angular-js/16829270#16829270) (also "Understanding Dependency Injection" on the AngularJS wiki), specifically the part on `$injector`, explains how DI works at a lower level, and may help you understand why certain code works or doesn't work. – Michelle Tilley Jul 04 '13 at 21:04
  • 1
    That's an outstanding article! +1 on both. – hughesdan Jul 04 '13 at 21:14

2 Answers2

21

When you create your controller:

angular.module('myApp.controllers', []).
controller('ImagesCtrl', ['$scope', '$http', function ($scope, $http) {
  // ...
}]);

The stuff inside the body of the controller function automatically has access to $scope and $http because of closures. Thus, there's no need to specify anything additional for a function on the $scope to have access to these things:

angular.module('myApp.controllers', []).
controller('ImagesCtrl', ['$scope', '$http', function ($scope, $http) {

  $scope.didSelectLanguage = function() {
    $http.jsonp('http://localhost:3000/image?quantity=1&language=' + this.language + '&Flag=&callback=JSON_CALLBACK');
      .success(function(data) {
        $scope.$parent.image = data;
      });
  }

}]);

When didSelectLanguage is run, it sees the references to $http, and reaches out of the function into the outer function to get the value of the reference; the same happens for $scope inside the success callback.

So, in short, there's no need to pass any arguments to your didSelectLanguage function, nor is there in this case any reason to use the $injector.

Michelle Tilley
  • 157,729
  • 40
  • 374
  • 311
1

With the help of Michelle Tilley's comment & article I solved the problem as follows. However, I'm going to keep the question open until someone else answers or until I understand enough to write an accompanying explanation.

controller('ImagesCtrl', ['$scope', '$http', '$injector', function ($scope, $http, $injector) {

    $scope.didSelectLanguage=function() {

            $http.jsonp('http://localhost:3000/image?quantity=1&language='+this.language+'&Flag=&callback=JSON_CALLBACK')
            .success(function(data){
            $scope.$parent.image = data;
            });

        }

  }])
Michelle Tilley
  • 157,729
  • 40
  • 374
  • 311
hughesdan
  • 3,019
  • 12
  • 57
  • 80