Angular.js - error with providerInjector - javascript

I have a problem with providers in angular, I get this error:
Row 2696: Error: Unknown provider: a
Using unminified angular v 1.06, Row 2696:
providerInjector = createInternalInjector(providerCache, function() {
throw Error("Unknown provider: " + path.join(' <- '));
}),
This is the code:
var myApp = angular.module('myApp', [], function ($interpolateProvider) {
$interpolateProvider.startSymbol('{[{');
$interpolateProvider.endSymbol('}]}');
});
myApp.directive('buttonsRadio', function() {
[...]
});
myApp.controller('MainController', function MainController ($scope) {
[...]
})
Any ideas?
Edit: Added error message:
Error: Unknown provider: aProvider <- a
createInjector/providerInjector<#/libs/angular.js:2696
getService#/libs/angular.js:2824
createInjector/instanceCache.$injector<#/libs/angular.js:2701
getService#/libs/angular.js:2824
invoke#/libs/angular.js:2842
instantiate#/libs/angular.js:2874
#/libs/angular.js:4759
applyDirectivesToNode/nodeLinkFn/<#/libs/angular.js:4338
forEach#/libs/angular.js:138
nodeLinkFn#/libs/angular.js:4323
compositeLinkFn#/libs/angular.js:3969
compositeLinkFn#/libs/angular.js:3972
nodeLinkFn#/libs/angular.js:4354
compositeLinkFn#/libs/angular.js:3969
publicLinkFn#/libs/angular.js:3874
bootstrap/resumeBootstrapInternal/</<#/libs/angular.js:963
Scope.prototype.$eval#/libs/angular.js:8011
Scope.prototype.$apply#/libs/angular.js:8091
bootstrap/resumeBootstrapInternal/<#/libs/angular.js:961
invoke#/libs/angular.js:2857
bootstrap/resumeBootstrapInternal#/libs/angular.js:960
bootstrap#/libs/angular.js:973
angularInit#/libs/angular.js:934
#/libs/angular.js:14756
f.Callbacks/n#http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js:2
f.Callbacks/o.fireWith#http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js:2
.ready#http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js:2
B#http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js:2
/libs/angular.js
Line 5704

Before running uglify or any other ofuscator/compression algorithm, you should run the grunt task ng-annotate which adds the dependencies as strings for you as an injectable array, this makes your code a lot cleaner as the injectable annotaion can be added automatically as a build step rather than having to manually code it.
myApp.controller('MainController', function MainController ($scope) {
[...]
})
Becomes:
myApp.controller('MainController', ['$scope', function MainController ($scope) {
[...]
}])
Take a look at: https://github.com/olov/ng-annotate
Update:
ng-min AngularJS Pre-minifier deprecated –> use ng-annotate

I assume you're using some kind of javascript obufuscator (Clousure, SquishIt, UglifyJS etc).
In this case you need to specify dependencies in such way:
var myApp = angular.module('myApp', [], ['$interpolateProvider',function ($interpolateProvider) {
$interpolateProvider.startSymbol('{[{');
$interpolateProvider.endSymbol('}]}');
}]);
myApp.directive('buttonsRadio', function() {
[...]
});
myApp.controller('MainController',['$scope', function MainController ($scope) {
[...]
}])
Note to specify dependenices for dependency injection - instead of passing function, you need to specify array with list of strings with names of objects to inject into parameters and the function itself.

Related

Angular Error: $injector:unpr Unknown Provider when separating files

I have the following code and it works fine:
app.main.js:
angular.module('app', ['ngAnimate', 'ui.router'])
.factory('_', function() {
return window._;
});
angular.module('app').run(['$route', '$rootScope', '$location', function ($route, $rootScope, $location) {
var original = $location.path;
$location.path = function (path, reload) {
if (reload === false) {
var lastRoute = $route.current;
var un = $rootScope.$on('$locationChangeSuccess', function () {
$route.current = lastRoute;
un();
});
}
return original.apply($location, [path]);
};
}]);
bservice:
angular.module('app')
.service('bService', ['$http', '_', function($http, _) { ...
But when I try to separate de factory to a different file I get the Angular Error: $injector:unpr Unknown Provider. This file looks like this:
angular.module('app').factory('_', function() {
return window._;
});
I also made sure that the factory file is included.
Thanks
EDIT
Full error:
Unknown provider: _Provider
I use gulp for the file merges. So everything is in one file.
Gulp didn't like the name factorys. Because of this my factory became damaged in the main .js file.
The solution was to rename the folder to anything els then factorys.

Can't access function in Angular.js service

I am trying to create and use a new service in AngularJS, however,
I get the following error -
Error message
ProjectService.one is not a function
The Javascript -
var app = angular.module('app', ['ngRoute']);
app.service('ProjectService', function () {
this.one = function one() {
console.log('test service');
};
});
app.controller('ProjectsController', ['$scope', function (ProjectService, Test) {
ProjectService.one();
}]);
There is something wrong in your controller declaration. Your ProjectService parameter matches the $scope service. Do this instead;
app.controller('ProjectsController', ['$scope', 'ProjectService', 'Test', function ($scope, ProjectService, Test) {
ProjectService.one();
}]);
The service-parameters must match the array of services (same number and order)
You've to inject the ProjectService and other required dependent modules as mentioned below:
app.controller('ProjectsController', ['$scope','ProjectService','Test', function ($scope,ProjectService, Test) {
ProjectService.one();
}]);

What's wrong with this factory dependencies issue?

I'm working with AngularJS.
I'd like to get a controller using a first factory which using another one.
It could be schematize like that:
MyCtrl -> Factory1 -> Factory2
So I tried to do in 3 different files (loaded in the following order):
Factory2.js
app.factory('Factory2', function () { ... })
Factory1.js
app.factory('Factory1',['Factory2', function (Factory2) { ... })
controller.js
app.controller('MyCtrl',['$scope', 'Factory1', function ($scope, Factory1) { ... })
And in my HTML I have:
<script src="services/factory2.js" type="text/javascript"></script>
<script src="services/factory1.js" type="text/javascript"></script>
<script src="controllers/controller.js" type="text/javascript"></script>
But it doesn't work and I've got this error Unknown provider: Factory2Provider <- Factory2 <- Factory1
What's wrong with my code? Am I missing something?
You can refactor your codes and use modules, in this way you will not need to use $inject
var app = angular.module('app', ['factories', 'mymodule']);
angular.module('factories', [])
.factory('Factory2', function () { })
.factory('Factory1', ['Factory2', function (Factory2) {
return myCustomFunction = function () {
alert('todo');
}
}]);
angular.module('mymodule', [])
.controller('MyCtrl', ['$scope', 'Factory1', function ($scope, Factory1) {
$scope.text = "testing";
}])
http://jsfiddle.net/kL78rdr3/3/
Why don't you use explicit injection with $inject? It is a better approach, because it gives you more control over the dependencies. For example:
userController.js
function userController (model, routeParams, searchService) {
//implementation
}
userController.$inject = ['$scope', '$routeParams', 'searchService'];
app.controller("userController", userController);
searchService.js
var searchService = function (http, log) {
//implementation
}
searchService.$inject = ["$http", "$log"];
app.factory("searchService", searchService);
This post may be useful: Explicit Dependency Injection

Angular + Requirejs - how to return multiple modules?

How can I return multiple angular modules in requirejs environment?
this is my app.js,
define([
'angular',
'angular-route',
'jquery'
], function (ng,ngRoute,$) {
'use strict';
console.log($('h1').length);
return ng.module('myApp', ['ngRoute']);
});
And I need a few more modules to return,
ng.module('myAppModule1', ['ngRoute']);
ng.module('myAppModule2', ['ngRoute']);
ng.module('myAppModule3', ['ngRoute']);
a controller example, for instance I want to get 'myAppModule3' in app.js,
define(['app'], function (app) {
var myAppModule = angular.module('myAppModule3');
myAppModule.controller('welcomeController', ['$scope', function($scope) {
//your minsafe controller
$scope.message = "Message from WelcomeController";
}]);
});
You could change app.js to return an object whose fields are the modules:
define([
'angular',
'angular-route',
'jquery'
], function (ng,ngRoute,$) {
'use strict';
console.log($('h1').length);
return {
myApp: ng.module('myApp', ['ngRoute']),
myAppModule1: ng.module('myAppModule1', ['ngRoute']),
myAppModule2: ng.module('myAppModule2', ['ngRoute']),
myAppModule3: ng.module('myAppModule3', ['ngRoute'])
};
});
And change your controller like this:
define(['app'], function (app) {
app.myAppModule3.controller('welcomeController', ['$scope', function($scope) {
//your minsafe controller
$scope.message = "Message from WelcomeController";
}]);
});
The generic (non-Angular specific) way is to use an object:
return {module1: /*..*/, module2: /*...*/ };
Then you just access to the values:
define(['app'], function (app) {
var module1 = app.module1;
});
However in Angular you just registered 'myAppModule1' in the Angular global. There is no need to do the object return, you can retrieve the registered module using the angular object:
define(['angular'], function (angular) {
var module1 = angular.module('myAppModule1');
// without extra parameter it tells angular to retrive an existing
// module
});
Update: I just realize that you did it in your code. It didn't worked? Maybe be you have a dependency issue, make sure that app.js is loaded first.

Error: Unknown provider - Karma, requirejs, angular

I get this error when i try to make a test
Error: [$injector:unpr] Unknown provider: $translateProvider <- $translate
I'm using karma with requirejs.
loadingCtrlSpec.js
define([
'angular',
'angular-mocks',
'app',
'angular-translate'
], function(angular, mocks, app) {
'use strict';
describe('loadingCtrl', function(){
var ctrl, scope, translate;
beforeEach(mocks.module('TestApp'));
beforeEach(inject(function($injector){
scope = $injector.get('$rootScope').$new();
translate = $injector.get('$translate');
}));
it("contains spec with an expectation", function() {
expect(true).toBe(true);
});
});
});
loadingCtrl.js
define(['angular'], function (angular) {
'use strict';
angular.module('TestApp', [])
.controller('loadingCtrl', ['$scope', '$translate', function($scope, $translate) {
$translate(['build.DEFAULT_EMAIL_SUBJECT','build.DEFAULT_EMAIL_NOTES']).then(function (translations) {
$scope.title = translations["build.DEFAULT_EMAIL_SUBJECT"];
$scope.notes = translations["build.DEFAULT_EMAIL_NOTES"];
});
}]); })
If i don't use angular-translate ($translate) everything is working so i don't think the problem is from karma.conf.js or test-main.js (require.conf for karma).
Your TestApp module will need to specify the pascalprecht.translate module as a dependency. Also be sure to include angular-translate as a dependency when defining your main module so the relevant script gets loaded:
define(['angular', 'angular-translate'], function (angular) {
angular.module('TestApp', ['pascalprecht.translate']);
});

Categories