I'm trying to load an authService into my application using AngularJS + RequireJS. The app, requires authService to load, and authService requires app to load. But I can't seem to get the load to work properly.
I've tried setting a main controller for the application that will use the authProvider, but if I do that I get the following error:
Error: [$injector:unpr] Unknown provider: authServiceProvider <- authService
If I try to inject the authService into the app, I get this error:
Error: [$injector:modulerr] Failed to instantiate module app due to:
[$injector:modulerr] Failed to instantiate module authService due to:
[$injector:nomod] Module 'authService' is not available! You either misspelled the module name or forgot to load it.
Both errors make sense to me, and I know why they happen. I just don't know if there's a way around it beyond including authService into app.js (which I would like to avoid)
Example code is below.
app.js
define(function (require) {
var angular = require('angular');
var ngRoute = require('angular-route');
var authService = require('authService');
var app = angular.module('app', ['ngRoute']);
app.init = function () {
console.log('init');
angular.bootstrap(document, ['app']);
};
app.config(['$routeProvider', function ($routeProvider) {
console.log('config');
}]);
app.run(function () {
console.log('run');
});
var appCtrl = app.controller('appCtrl', function (authService) {
});
return app;
})
authentication.js
require(['app'], function (app) {
return app.factory('authService', ['$http', function ($http) {
return {
test: function () {
return this;
}
}
}]);
});
config.js
require.config({
baseUrl:'app',
paths: {
'angular': '../bower_components/angular/angular',
'angular-route': '../bower_components/angular-route/angular-route',
'angularAMD': '../bower_components/angularAMD/angularAMD',
'ngDialog': '../bower_components/ngDialog/js/ngDialog',
'ngCookies': '../bower_components/angular-cookies/angular-cookies',
'authService': 'services/authentication'
},
shim: {
'angular': {
'exports': 'angular'
},
'angular-route': ['angular'],
'angularAMD': ['angular'],
'ngCookies': ['angular']
},
priority: [
'angular'
],
deps: [
'app'
]
});
require(['app'], function (app) {
app.init();
});
index.html
<!DOCTYPE html>
<html lang="en" ng-controller="appCtrl">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div ng-view></div>
<script src="bower_components/requirejs/require.js" data-main="app/config.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.js"></script>
</body>
</html>
You described a circular reference per "The app, requires authService to load, and authService requires app to load" and there is simply no solution for it.
However, looking at the sample code you provided, your true dependency is:
authService
needs to be created and made available for app
appCtrl
created in app
requires authService
Assuming that's your only dependency, you can use angularAMD
to create authService
:
require(['angularAMD'], function (angularAMD) {
angularAMD.factory('authService', ['$http', function ($http) {
return {
test: function () {
return this;
}
}
}]);
});
And make sure to use angularAMD
to bootstrap app
:
define(['angularAMD', 'angular-route', 'authentication'], function (require) {
var app = angular.module('app', ['ngRoute']);
...
return return angularAMD.bootstrap(app);
}]);
Take a look at Loading Application Wide Module for more details.