Uncaught error injector modulerr

AngularJS dependency injection can fail for reasons.  Through this, we will try to overcome some reasons for such failures and solutions.

If you are into any serious Angular development you see such errors once too often:

Uncaught Error: [$injector:modulerr] Failed to instantiate module app due to:
Error: [$injector:modulerr] Failed to instantiate module ngRoute due to:
Error: [$injector:nomod] Module 'ngRoute' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.

Or:

Error: [$injector:unpr] Unknown provider: scopeProvider <- scope
http://errors.angularjs.org/1.2.26/$injector/unpr?p0=scopeProvider%20%3C-<div ng-view="" class="ng-scope">

This is a clear case of Dependency Injection failing. If you are one of the early adopters of Angular you, will appreciate how descriptive these messages have become as the framework has evolved. For example the one above clearly mentioning ngRoute module was not found.

Angular dependency injection can fail for number of reasons.  Through this post we will try to understand some common reason for such failures and their resolution. If next time you encounter such errors remember to refer back to this post.

Misspelled dependencies

By far the most common cause of DI failures. Remember dependencies names are case sensitive, hence need to be reproduced verbatim. $scope is not scope, sope, or scoop :). Double check your dependency names.

Order and Count of dependencies

Again very common issue when using minification friendly syntax. These are all are incorrect:

 // $route -> $scope, $scope->$route
.controller('Ctrl1',['$scope', '$route', function($route, $scope)    

//$routeParams is undefined
.controller('Ctrl2',['$scope', '$route', function($scope,$route,$routeParams)     

 // Nothing is injected, so its fine.
.controller('ctrl3',['$scope', '$route','$routeParams', function($scope,$route)

The biggest problem in this scenario is that there are no failures just incorrect assignment and hence is hard to debug.

Duplicate Module declaration

There is a subtle difference between module declaration and getting a reference to an exiting module. The statement below declares a module controllers:

angular.module('controllers',[])  // Second parameters to specify dependency

Whereas this one retrieves the module controllers:

angular.module('controllers')  // No second parameter

If we unknowingly use the first syntax multiple times across the app,  we are actually overwriting the existing module declaration, and the direct impact of this is failed dependency injection. Again a difficult issue to debug. If you see dependency injection failure for controllers, filters, services or directives that seem to be available and there is no typo error, duplicate module declaration could be a prime reason for this failure.

The fix here is simple just make sure module declaration for any module happens only once in the entire app.

Module not injected

With third party components we always make sure to inject module dependencies before using the component. But with framework service that have moved over time  into their own modules we may overlook the change.

Angular routing is a prime example of this. Since 1.2.0  Angular Routing is in a separate module ngRoute (which include $route, $routeProvider and $routeParams services) instead of the core module (changelog). If you are getting error injecting standard AngularJS service it’s better to refer to the documentation and double check which module the dependency is part of.

Remember in Angular ng is core module.  Anything other than core (ng) has to be injected.

Dependency resolution with $routeProvider resolve

$routeProvider allows us to inject dependencies using resolve property. Such dependencies can only be injected into controllers that have been declared in the route definition, such as:

$routeProvider.when('/page1', { 
   templateUrl: 'page1.html',
   controller:'Page1Controller' , 
   resolve: {
      data:function(){ return "someData";} 
   }
});

Only Page1Controller created through the route resolution process is injected with the dependency (data).

The below mechanism of loading controller throws dependency injection error:

<div ng-controller="Page1Controller"></div>

Injecting dependency at config stage

The only things allowed to be injected at the config state are constants and providers. Forget about injecting any standard service at config stage, be it Angular services (like $http, $location, $timeout) or any custom service we create. This piece of code will fail with error Error: [$injector:unpr] Unknown provider: $http:

.config(['$routeProvider','$http', function ($routeProvider) {

At config stage dependencies are not ready to be used and hence Angular safeguards against any accidental injection of such dependencies.

I have covered most of the dependency injection errors that are common.Hope this post helps people stuck with DI issues in Angular.

I have also created a fiddle highlighting most of the issues described above. Go check it out!

Don’t miss out on the latest tips, tools, and tactics at the forefront of HR and Employee

Старый

13.02.2015, 12:39

Профессор

Отправить личное сообщение для Царь Леонид

Посмотреть профиль

Найти все сообщения от Царь Леонид

 

Регистрация: 22.08.2013

Сообщений: 217

Ошибка Uncaught Error: [$injector:modulerr]

Вобщем гугл показал, что такая ошибка не редкость, только лечили ее везде разными способами, а так как я не очень понимаю, что там происходит, то хочу сам разобраться. Индексная страница:

<!doctype html>
<html ng-app="usercat">
  <head>
    <title>My Angular App</title>
	<meta charset="utf-8">
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"></script>
	<script src="js/app.js"></script>
	<script src="js/controllers.js"></script>
  </head>
<body ng-controller="UserListCtrl">
	...
</body>
</html>

Файл app.js

angular.module('usercat', []).
  config(['$routeProvider', 
  function($routeProvider) {
    $routeProvider.
        when('/messages', {
          templateUrl: 'partials/messages.html',
          controller: 'UserListCtrl'}).
        otherwise({
          redirectTo: '/'
        });
  }]);

На всяк случай контроллер:

function UserListCtrl($scope) {
  $scope.users = [
    ...
  ];
   ...
}

В директории partials/messages лежит простая страница с текстом.



Последний раз редактировалось Царь Леонид, 13.02.2015 в 12:42.

Ответить с цитированием

Старый

13.02.2015, 13:27

Аватар для ksa

CacheVar

Отправить личное сообщение для ksa

Посмотреть профиль

Найти все сообщения от ksa

 

Регистрация: 19.08.2010

Сообщений: 13,992

Царь Леонид, для разборов нужна кагбе модель на которой и другие могут получить аналогичную проблему… А ты пока показал какие-то огрызки.
Их даже в кучу не собрать…

Ответить с цитированием

Старый

13.02.2015, 13:41

Профессор

Отправить личное сообщение для Царь Леонид

Посмотреть профиль

Найти все сообщения от Царь Леонид

 

Регистрация: 22.08.2013

Сообщений: 217

ksa,
Полностью с тобой согласен, просто я думал, что где-то уж явно накосячил и это сразу будет видно Вот ссылка на песочницу http://learn.javascript.ru/play/xj4Kkb, все работает до тех пор, пока не указать модуль <html ng-app=»usercat»>



Последний раз редактировалось Царь Леонид, 13.02.2015 в 13:43.

Ответить с цитированием

Старый

13.02.2015, 13:53

Аватар для ksa

CacheVar

Отправить личное сообщение для ksa

Посмотреть профиль

Найти все сообщения от ksa

 

Регистрация: 19.08.2010

Сообщений: 13,992

Файл app.js

angular.module('usercat', []).
  config(['$routeProvider', 
  function($routeProvider) {
    $routeProvider.
        when('/messages', {
          templateUrl: 'partials/messages.html',
          controller: 'UserListCtrl'}).
        otherwise({
          redirectTo: '/'
        });
  }]);

Давай сличим т.с. с примером из первоисточника…

angular.module('phonecat', []).
  config(['$routeProvider', 
  function($routeProvider) {
    $routeProvider.
        when('/phones', {
          templateUrl: 'partials/phone-list.html',
          controller: 'PhoneListCtrl'}).
        when('/phones/:phoneId', {
          templateUrl: 'partials/phone-detail.html', 
          controller: 'PhoneDetailCtrl'
        }).
        otherwise({
          redirectTo: '/phones'
        });
  }]);

http://angular.ru/tutorial/step_07

Заметь куда делается redirectTo, а он делается на, описанную выше, маску хеш-фрагмента.

А, что у тебя?

Сообщение от Царь Леонид
Посмотреть сообщение

otherwise({
          redirectTo: '/'
        });

Такая маска хеш-фрагмента у тебя не описана.

Ответить с цитированием

Старый

13.02.2015, 13:54

Аватар для ksa

CacheVar

Отправить личное сообщение для ksa

Посмотреть профиль

Найти все сообщения от ksa

 

Регистрация: 19.08.2010

Сообщений: 13,992

Сообщение от Царь Леонид

все работает до тех пор, пока не указать модуль <html ng-app=»usercat»>

Значит все дело в его неправильном описании или инициализации.

Ответить с цитированием

Старый

13.02.2015, 14:32

Аватар для ksa

CacheVar

Отправить личное сообщение для ksa

Посмотреть профиль

Найти все сообщения от ksa

 

Регистрация: 19.08.2010

Сообщений: 13,992

Начнем с работающего примера…

<!doctype html>
<html ng-app>
  <head>
    <title>My Angular App</title>
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"></script>
<script type='text/javascript'>
function UserListCtrl($scope) {
	$scope.users = [
		{
			"name": "Homer S.",
			"phone": "(999)321-467",
			"message": "Сообщение на внутренней странице Homer S."
		},
		{
			"name": "Bart S.",
			"phone": "(999)821-568",
			"message": "Сообщение на внутренней странице Bart S."
		},
		{
			"name": "Lisa S.",
			"phone": "(999)865-234",
			"message": "Сообщение на внутренней странице Lisa S."
		},
		{
			"name": "Alex V.",
			"phone": "(999)865-284",
			"message": "Сообщение на внутренней странице Alex V."
		}
	];
	$scope.orderProp = "count";/*сортировка модели при открытии страницы*/
	$scope.ordering = function(Name){/* функция сортировки модели */
		$scope.orderProp = Name;
	};
	$scope.remove = function(item){/*удаление объекта из модели*/
		var index = $scope.users.indexOf(item)
		$scope.users.splice(index, 1)
	};
	$scope.addUser = function(){/*добавление элемента в модель*/
		$scope.users.push({
			name:$scope.addName, 
			phone:$scope.addPhone, 
			message:$scope.addMessage
		});
		$scope.addName = '';/* reset поля имени*/
		$scope.addPhone = '';/*reset поля телефона*/
		$scope.addMessage = '';/*reset поля сообщения*/
	}; 
};	
</script>
  </head>
  <style>
  th.change{
	cursor:pointer;
	color:blue;
  }
   th.change:hover{
	text-decoration:underline;
  }
  .container{
	width:900px;
	margin:0 auto;
  }
  </style>
<body ng-controller='UserListCtrl'>
<div>

	<div class="container">
		<div class="row">
			<div class="col-md-12">
				<table class="table table-bordered">
				   <th class="change" ng-click="ordering('article')">
					По номеру
				  </th>
				  <th class="change" ng-click="ordering('name')">
					По имени
				  </th>
				  <th class="change" ng-click="ordering('phone')">
					По телефону
				  </th>
				  <th>
					Всего пользователей:{{users.length}}
				  </th>
				  <tr ng-repeat="user in users | orderBy:orderProp">
						<td>{{$index+1}}</td>
							<td><a href="#/messages">{{user.name}}</a></td>
						<td>{{user.phone}}</td>
						<td><input value="Удалить" type="button" ng-click="remove($index)"></td>
				  </tr>		
				</table>
				<div class="col-md-12">
					<form ng-submit="addUser()" class="form-inline">
					  <div class="form-group">
						<label for="exampleInputName2">Имя</label>
						<input ng-model="addName" type="text" class="form-control" id="exampleInputName2" placeholder="Jane Doe">
					  </div>
					  <div class="form-group">
						<label for="exampleInputEmail2">Телефон</label>
						<input ng-model="addPhone" class="form-control" id="exampleInputEmail2" placeholder="(999)333-444">
					  </div>
					  <div class="form-group">
						<textarea ng-model="addMessage" class="form-control" id="exampleInputEmail3" placeholder="Введите ваше сообщение..."></textarea>
					  </div>
					  <button type="submit" class="btn btn-default">Добавить</button>
					</form>
				</div>
			</div>	
		</div>
	</div>	

</div>
</body>
</html>

Ответить с цитированием

Старый

13.02.2015, 14:46

Аватар для ksa

CacheVar

Отправить личное сообщение для ksa

Посмотреть профиль

Найти все сообщения от ksa

 

Регистрация: 19.08.2010

Сообщений: 13,992

Далее в первоисточнике помимо

<script src="bower_components/angular/angular.js"></script>

Подключают еще два скрипта!

<script src="bower_components/angular-route/angular-route.js"></script>
<script src="bower_components/angular-resource/angular-resource.js"></script>

Коих у тебя нет. Видать без них никакой маршрутизации не получится.

Ответить с цитированием

Старый

13.02.2015, 14:50

Профессор

Отправить личное сообщение для Царь Леонид

Посмотреть профиль

Найти все сообщения от Царь Леонид

 

Регистрация: 22.08.2013

Сообщений: 217

Такая тема, начиная с версии 1.1.6 надо подключать ngRoute, в заголовке индекс.хтмл указываем

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0rc1/angular-route.min.js"></script>

В модуле (у меня файл app.js) указываем роутер

angular.module('usercat', ['ngRoute']).

Ошибка не вылазит, но и перехода не происходит (это уже наверное мой косяк где-то, сегодня мой второй день знакомства с ангуляром, так что мне можно)) .ksa спасибо за участие.

Ответить с цитированием

Старый

13.02.2015, 16:13

Аватар для ksa

CacheVar

Отправить личное сообщение для ksa

Посмотреть профиль

Найти все сообщения от ksa

 

Регистрация: 19.08.2010

Сообщений: 13,992

Сообщение от Царь Леонид

спасибо за участие

Ты потом сваргань пример «для посмотреть». А то ведь я то же его изучаю…

Ответить с цитированием

While injecting datatables and datatables.buttons in angular.module like this
angular.module(‘myApp’,[‘datatables’, ‘datatables.buttons’]) I get Uncaught Error: [$injector:modulerr] in console
I do not see any other error and I have added all dependencies in my vendor folder and copied on to master.dust which is the common html template for all html files
My code is as below

angular.module('myApp',['datatables', 'datatables.buttons'])
    .controller('ViewCtrl', function ($scope, $state, $filter, sharedServices, DTOptionsBuilder, DTColumnBuilder, DTColumnDefBuilder, $q, $stateParams, $sce, $interval, $uibModal) {
       $scope.dtOptions = DTOptionsBuilder.newOptions()
        .withPaginationType('full_numbers')
        .withDisplayLength(2)
        .withDOM('pitrfl')
        .withButtons([{
                extend: 'excelHtml5',
            }
        ]);

And the dependencies are:

<script src="{context.links.resourceBaseUrl|s}/vendor/datatables/js/jquery.dataTables.js"></script>
<script src="{context.links.resourceBaseUrl|s}/vendor/datatables/js/jquery.dataTables.min.js"></script>
<script src="{context.links.resourceBaseUrl|s}/vendor/datatables.net-bs/dataTables.bootstrap.js"></script>
<script src="{context.links.resourceBaseUrl|s}/vendor/datatables.net-bs/dataTables.bootstrap.min.js"></script>


<script src="{context.links.resourceBaseUrl|s}/vendor/datatables/angular-datatables/angular-datatables.min.js"></script>
<script src="{context.links.resourceBaseUrl|s}/vendor/datatables-responsive/dataTables.responsive.js"></script>
<script href="{context.links.resourceBaseUrl|s}/vendor/angular/angular.js"></script>
<script href="{context.links.resourceBaseUrl|s}/vendor/datatables/angular-datatables/angular-datatables.min.js"></script> 

<script href="{context.links.resourceBaseUrl|s}/vendor/datatables.net-buttons/dataTables.buttons.min.js"></script>

<script href="{context.links.resourceBaseUrl|s}/vendor/datatables.net-buttons/buttons.colVis.min.js"></script>
<script href="{context.links.resourceBaseUrl|s}/vendor/datatables.net-buttons/buttons.flash.min.js"></script>
<script href="{context.links.resourceBaseUrl|s}/vendor/jszip/jszip.min.js"></script>
<script href="{context.links.resourceBaseUrl|s}/vendor/datatables.net-buttons/buttons.html5.min.js"></script>
<script href="{context.links.resourceBaseUrl|s}/vendor/datatables.net-buttons/buttons.print.min.js"></script>
<script href="{context.links.resourceBaseUrl|s}/vendor/datatables/angular-datatables/plugins/buttons/angular-datatables.buttons.min.js"></script>

Kindly help

Edited by Colin — Syntax highlighting. Details on how to highlight code using markdown can be found in this guide.

Понравилась статья? Поделить с друзьями:
  • Uncaught error extension context invalidated
  • Uncaught error expected the reducer to be a function
  • Uncaught error dropzone already attached
  • Uncaught error class evtimer not found
  • Uncaught error call to undefined function imagecreatefrompng