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;
            });

        }

  }])
2
  • 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? (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. Commented Jul 4, 2013 at 21:04
  • 1
    That's an outstanding article! +1 on both. Commented Jul 4, 2013 at 21:14

2 Answers 2

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.

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

Comments

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;
            });

        }

  }])

Comments

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.