I am trying to run my AngularJS front-end on server. I am using Yeoman to build the app. I upload the very basic hello world app and I get plain HTML text withou JavaScript loaded. Console in Chrome says this:
Error: Unknown provider: aProvider <- a
at Error (<anonymous>)
at http://../scripts/vendor/d10639ae.angular.js:2627:15
at Object.getService [as get] (http://../scripts/vendor/d10639ae.angular.js:2755:39)
at http://../scripts/vendor/d10639ae.angular.js:2632:45
at getService (http://../scripts/vendor/d10639ae.angular.js:2755:39)
at invoke (http://../scripts/vendor/d10639ae.angular.js:2773:13)
at Object.instantiate (http://../scripts/vendor/d10639ae.angular.js:2805:23)
at http://../scripts/vendor/d10639ae.angular.js:4620:24
at update (http://../scripts/vendor/d10639ae.angular.js:13692:26)
at http://../scripts/vendor/d10639ae.angular.js:8002:24 d10639ae.angular.js:5526
Anybody experiencing the same and knows the way out?
EDIT:
'use strict';
yoAngApp.controller('MainCtrl',['$scope', '$window', function($scope, $window) {
$scope.awesomeThings = [
'HTML5 Boilerplate',
'AngularJS',
'Testacular'
];
$scope.records = [{ title : 'one' }, { title : 'two' }, { title : 'three' }, { title : 'four' }];
$scope.greet = function() {
($window.mockWindow || $window).alert('Hello ' + $scope.name);
}
}]
);
As @ŁukaszBachman suggested, you may use $inject annotation or you may use Inline Annotation if you want to:
- Keep your dependency annotations close to your function definitions (for better readability).
- Stay away from polluting global namespace.
app.controller('UsersController',
[
'$scope', 'UserService', '$location', '$routeParams',
function($scope, User, $location, $routeParams) {
$scope.user = User.get({id: $routeParams.id});
...
}
]
);
I'm pretty sure that you have used code minifier for production server, am I right?
Anyways, the folks from Angular Js made pretty clear that using minifier can mess up Dependency Injection if it's not done properly. Why this happens? Have a look:
Dependency Injection vs. Code Minifier
function MyController($scope, $log) { ... }
In the snippet above you are making use of implicit DI. Angular sees variable $scope
and tries to match it with any managed dependency. In this example it will match it to the $scope
object.
This, however, will not work after code minifying, as the result will look somehow like this:
function a(b, c) { ... }
Since variable and function names were minified, Angular cannot know what exactly an "a" is.
Solution
Use explicit Dependency Injection configuration.
var MyController = function($scope, $log) { ... }
MyController.$inject = ['$scope', '$log'];
In this snippet you are defining which dependencies should be resolved by attaching array of their names to special property of controller (or service) called $inject
. Now Angular will know that it should resolve $scope
and pass it as first parameter to MyController
. Then it will resolve $log
and pass it as second parameter.
It's all possible because minifiers won't modify the contents of string variables.