0

I'm new at Angular and trying to do a basic dependency injection to get the hang of it. In this example I'm trying to dependency inject a service to a controller, and I'm getting the following error.

Error: [$injector:unpr] Unknown provider: $scopeProvider <- $scope <- testInjection

Plunker

Html:

<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.4.x" src="https://code.angularjs.org/1.4.0-rc.1/angular.js" data-semver="1.4.0-rc.1"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <p>Hello {{name}}!</p>
  </body>

</html>

js:

var app = angular.module('plunker', []);

app.controller('MainCtrl', ['testInjection',function($scope) {
  $scope.name = 'World';
}]).factory('testInjection', ['$scope', function($scope) {

  }]);
Ben Pearce
  • 6,884
  • 18
  • 70
  • 127
  • 4
    The `$scope` can *ONLY* be injected in controllers (standalone or in directives). Your service must use something else (and I would even consider if using a view construct, like the scope, in a service is sane anyway). – Nikos Paraskevopoulos May 06 '15 at 07:56
  • 1
    You’d better have a look at this answer: http://stackoverflow.com/questions/22898927/injecting-scope-into-an-angular-service-function – Philipp Andreychev May 06 '15 at 08:07

3 Answers3

0

You should do this :

app.factory('testInjection', ['$scope', function($scope) {

 }]);

app.controller('MainCtrl', ['$scope', 'testInjection',function($scope, testInjection) {
  $scope.name = 'World';
}]);

It's better to define your service (factory) before. And the problem here is that even if the scope is injected in the service, you have to inject it again in the controller.

Mathieu Bertin
  • 1,634
  • 11
  • 11
  • why is it better to declare the factory before? also, it actually does not make sense to inject `$scope` into a service.. – fusio May 06 '15 at 08:48
  • I agree with the fact that it doesn't make sens to inject scope, because a service should be context less... For the service before the controller, it is just a convention that i use because controller use it so it should be define before even if in that case it will work anyway. – Mathieu Bertin May 06 '15 at 08:54
0

As Nikos said, don't try to inject the scope object into a service or factory.

For my angular projects, I create a new file for each controller/service/factory/directive. The setup of these files look like this:

A factory:

(function () {
    'use strict';
    angular.module('MyModule')
           .factory('someService', function () {
               var service = {
                   myFunction: function () { 
                       return "Hello";
                   }
               };

               return service;
           });
})();

A controller:

(function () {
    'use strict';
    angular.module('MyModule')
           .controller('someCtrl', ['$scope', 'someService', function ($scope, someService) {
               $scope.name = "World";
               $scope.message = someService.myFunction() + " " + $scope.name;
           }]);
})();

Beware, the above syntax only retrieves a existing module. See Angular Modules under "Creation versus Retrieval". I have another file which creates the module using the same syntax but with brackets for importing other modules.

You should take a look at the angular docs for more information and examples.

Kaj
  • 333
  • 2
  • 8
  • Thanks for your answer, as I said I'm new so it might take me a while to select the best answer. Using your technique do you put each controller/service/factory/directive in it's own module, and then inject dependencies module to module? – Ben Pearce May 06 '15 at 23:48
  • No, it's using the same module with the name "MyModule". You could divide your code into multiple modules and inject these into other modules, but I think that's a bit advanced for this example. – Kaj May 07 '15 at 07:07
0

I have modified your plunker here. Please check the way you define a service and the way you inject it. It does not matter even if you define it after the controller. Also, the error was because your factory function did not return anything. Fixed that as well.

Your code should look like:

var app = angular.module('plunker', []);

app.controller('MainCtrl'['$scope','testInjection',function($scope,testInjectio)
 {
  $scope.name = testInjection;
}]).factory('testInjection', function() {
       return "ABC"
  });
manasi sakhare
  • 1,051
  • 7
  • 18