162

The following file "works" (the sense that it does not throw any errors):

<!doctype html>
<html ng-app="modx">
    <script src="http://code.angularjs.org/angular-1.0.0rc7.js"></script> 
    <script>
        angular.module("modx", [], function($routeProvider) {
        });
    </script>
</html>

but this

<!doctype html>
<html ng-app="modx">
    <script src="http://code.angularjs.org/angular-1.0.0rc7.js"></script>
    <script>
        angular.module("modx", [], function($routeProvider, $rootScope) {
        });
    </script>
</html>

gives the error:

Error: Unknown provider: $rootScope from modx
Source File: http://code.angularjs.org/angular-1.0.0rc7.js
Line: 2491

WTF?

Onur Yıldırım
  • 32,327
  • 12
  • 84
  • 98
Michael Lorton
  • 43,060
  • 26
  • 103
  • 144

3 Answers3

307

You can not ask for instance during configuration phase - you can ask only for providers.

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

// configure stuff
app.config(function($routeProvider, $locationProvider) {
  // you can inject any provider here
});

// run blocks
app.run(function($rootScope) {
  // you can inject any instance here
});

See http://docs.angularjs.org/guide/module for more info.

Joseph Silber
  • 214,931
  • 59
  • 362
  • 292
Vojta
  • 23,061
  • 5
  • 49
  • 46
  • 9
    Thanks, it makes perfect sense, but how did you know that? Was it in the docs? – Michael Lorton May 07 '12 at 21:55
  • 143
    @Mavolio No, he is one the 3 core developers. – ChrisOdney Jun 06 '12 at 19:36
  • 8
    Well, FWIW, it is in the docs now, under the "Module Loading & Dependencies" section. – Mark Rajcok Oct 02 '12 at 18:41
  • 1
    @vojta But what if I need to pass parameter from outside and use it in `config` ? say root path within asp.net app ? I just don't want to use global variables and wanted to use `ng-init='root:<%= myroot %>'` and use `root` value into `module.config`. – vittore May 26 '13 at 19:58
  • @vittore not sure I understand - but if the value from outside is in the global state (say on window), you can just read it from there... You can't access global window from Angular expression (that's intentional). – Vojta Jul 30 '13 at 03:03
  • @Vojta my point is that using `ng-init="root:'\local\js\app'"` (where this root is dynamic and inserted when html page renders) seemed to be reasonable way of passing param into angular app, but i can't access this `root` value in config. – vittore Jul 30 '13 at 15:21
  • 7
    @vittore I think, putting this "outside" config into the global window is fine. Or having one module that defines all this stuff and then you load it in your app - eg. `angular.module('config', []).constant('appRoot', '/local/js/app');` (this code would be generated by your server (you could even generate it as a JS file, rather then inlining into the html file). Then, your app loads this module and therefore has access to `appRoot`. – Vojta Aug 22 '13 at 19:21
  • How to use services like `$location` `$state` in config() block ? or how to change `$state.param` in run() block? – DragonKnight Nov 14 '17 at 02:18
7

I've found the following "pattern" to be very useful:

MainCtrl.$inject = ['$scope', '$rootScope', '$location', 'socket', ...];
function MainCtrl (scope, rootscope, location, thesocket, ...) {

where, MainCtrl is a controller. I am uncomfortable relying on the parameter names of the Controller function doing a one-for-one mimic of the instances for fear that I might change names and muck things up. I much prefer explicitly using $inject for this purpose.

Ram Rajamony
  • 1,717
  • 15
  • 17
  • That's neat; but how do you access `MainCtrl` like that? – f1lt3r Jan 05 '16 at 20:11
  • I know your comment is old but it is worth responding to questions for future's sake. Modules/controllers can be defined like this so you can access them in this way: `angular.module('myMod', []).controller('theController', controllerFunction); controllerFunction.$inject = []; function controllerFunction() { }` – O'Mutt Aug 18 '16 at 13:29
1

I don't suggest you to use syntax like you did. AngularJs lets you to have different functionalities as you want (run, config, service, factory, etc..), which are more professional.In this function you don't even have to inject that by yourself like

MainCtrl.$inject = ['$scope', '$rootScope', '$location', 'socket', ...];

you can use it, as you know.

Devid Farinelli
  • 7,514
  • 9
  • 42
  • 73
Hazarapet Tunanyan
  • 2,809
  • 26
  • 30