I'm using AngularAMD + RequirsJS for a single page app and I'm having some issues when injecting a service in the app.js file.
Here the code:
login_service.js
define(['app'], function(app) {
'use strict';
app.service('loginService', function($location, $state, Restangular) {
return {
login: function(data, scope) {},
logout: function() {},
isLogged: function() {}
}
});
});
app.js
define(['angularAMD', 'restangular', 'angular-ui-router'], function(angularAMD) {
'use strict';
var app = angular.module('MyApp', ['restangular', 'ui.router', 'loginService']);
app.run(function($rootScope, $state, $stateParams, $location, loginService) {
console.log(loginService)
/*
Error: [$injector:modulerr] Failed to instantiate module MyApp due to: [$injector:modulerr]
Failed to instantiate module loginService due to:
$injector:nomod] Module 'loginService' is not available! You either misspelled the module name or forgot to load it.
*/
});
app.config(function($stateProvider, $urlRouterProvider, $i18nextProvider, RestangularProvider) {
});
});
I would liked to access the loginService in the run function but can't as I keep getting the "Failed to instantiate module MyApp" error message.
I've tried to load the login service file as follow:
define(['angularAMD', 'restangular', 'angular-ui-router', 'services/login_service'], function(angularAMD) {
});
But then I have another error stating that app is undefined in the Login Service.
Thank you very much for your helps.
David
It is happeing because 'loginService' is not a module it's a service and you cannot add 'loginService' (service) to the module you can only add only module to another module.
you can do one thing :-
var app = angular.module('loginService',[]);
app.service('loginService', function($location, $state, Restangular) {
return {
login: function(data, scope) {},
logout: function() {},
isLogged: function() {}
}
});
Ps:- I am not sure about this :-P
The problem is caused by the fact that requireJS loads the files dynamically and this assures you that the files are already loaded before it runs the code.
You should do the following:
Remove the ng-app from your html
Use a manual bootstrapping:
angular.element().ready(function(){
angular.bootstrap(document,['MyApp']);
});
Related
I need a help. I use Angularjs 1.6 and I want just simply to inject a service from diff file in a controller. Looks pretty easy, aha)
Before I read this:
AngularJS: Service in different file.
But it didn't work in my case.
My code looks next:
app.js
angular.module('myApp', ['formService', 'formLogic'])
component.js
angular.module('formLogic',[])
.component('formLogic',{
templateUrl: './templates/form-logic.html',
controller: function ($scope, formService){
}
});
service.js
angular.module('formService',[])
.service('FormService', function($http){
});
But I got this error: Error: $injector:unpr Unknown Provider
Thanks for your help!
Don't give your modules the same name as your providers (don't name both your module and your component "formLogic").
Add your "formService" module as a dependency on your "formLogic" module.
You have called your service "FormService" and are trying to inject "formService" into your component controller. "formService" is not a service that you have defined, it's the name of your module.
To inject component and services from different module. Can inject the module.
component.js
angular.module('anotherModule',[])
.component('formLogic',{
templateUrl: './templates/form-logic.html',
controller: function ($scope, formService){
}
});
service.js
angular.module('anotherModule')
.service('formService', function($http){
});
so no can use formService and formLogic from myApp module
like:
app.js
angular.module('myApp', ['anotherModule']) // injected `anotherModule` in `myApp` modele
mainController.js
angular.module('myApp').controller('MainCtrl', function($scope, formService) {
// can access `formService` from here
});
OR
you can use same module like:
var app = angular.module('myApp', []);
app.component('formLogic',{
templateUrl: './templates/form-logic.html',
controller: function ($scope, formService){
// ...
}
});
app.service('formService', function($http){
//.....
});
app.controller('MainCtrl', function($scope, formService) {
// can access `formService` from here
});
When passing this function that includes $routeProvider into a module definition, how do you mock/inject it properly in spec?
module.js
angular.module('myModule', [
// Without the function($routeProvider) below the test passes. With it, it fails.
function($routeProvider) {
$routeProvider.when('/some/url/:id', {templateUrl: 'template.html', reloadOnSearch: false});
}
])
myModuleCtrl.js
angular.module('myModule')
.controller('myModuleCtrl', [
'$scope',
function ($scope) {
$scope.testMethod = function () {
alert('Test Me!');
}
}
]);
myModuleCtrl.spec.js
describe('myModuleCtrl', function () {
var controller;
var $scope;
beforeEach(angular.mock.module('myModule'));
beforeEach(function () {
$scope = {};
});
beforeEach(angular.mock.inject(function ($rootScope, $controller) {
controller = $controller('myModuleCtrl', {'$scope': $scope});
}));
describe('when doing stuff', function() {
it('does other stuff', function() {
$scope.testMethod();
});
});
});
As commented in module.js, without the $routeProvider line the spec passes. With it, it fails with the following message:
Error: [$injector:modulerr] Failed to instantiate module myModule due to:
Error: [$injector:modulerr] Failed to instantiate module function ($routeProvider) due to:
Error: [$injector:unpr] Unknown provider: $routeProvider
What needs to be done in the spec file to get this module to load (including the $routeProvider)?
Your module should have injected dependency ngRoute
angular.module('myModule', ['ngRoute'])
Samething should be there for the test,
beforeEach(angular.mock.module('myModule',['ngRoute']));
I have angular script post.js and test for it post_test.js.
my post.js file
var Post = angular.module('Post', []);
Post
.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/post', {
controller: 'PostCtrl',
templateUrl: 'src/posts/partials/post.html'
})
;
}]);
and my post_test.js file:
'use strict';
describe('Post module', function() {
beforeEach(module('Post'));
describe('Post controller', function(){
it('should ....', inject(function($controller) {
//spec body
var PostCtrl = $controller('PostCtrl');
expect(PostCtrl).toBeDefined();
}));
});
});
in karma.conf.js I load
files: [
'app/components/angular/angular.js',
'app/components/angular-route/angular-route.js',
'app/components/angular-mocks/angular-mocks.js',
'app/app.js',
'app/src/**/*.js' // post.js, post_test.js
],
Everything seems OK, but angular returns this error:
Error: [$injector:modulerr] Failed to instantiate module Post due to:
Error: [$injector:unpr] Unknown provider: $routeProvider
I don't know why. I load angular-route.js before post.js. I've checked and it loads correctly. I've put alert(1) before defining $routeProvier and I've seen it in console. So this file is loading correctly, but in next file - test file it still doesn't work.
ngRoute module should be loaded as well.
Replace:
var Post = angular.module('Post', []);
with:
var Post = angular.module('Post', ['ngRoute']);
I'm using Jasmine for testing AngularJS controller and I'm struggling to find a way of injecting $routeProvider into the module.
Here's my controller:
var app = angular.module('testApp', []);
app.config(['$routeProvider',
function ($routeProvider) {
$routeProvider.
when('/smth', {
templateUrl: 'smth.html',
controller: 'testController'
});
}]);
app.controller('testController', ['$scope', function ($scope) {
$scope.data = 'GG';
}]);
Here's my test:
describe('Test Suite', function () {
var myScope, ctrl;
beforeEach(module('testApp'));
beforeEach(inject(function ($controller, $rootScope) {
myScope = $rootScope.$new();
ctrl = $controller('testController', {
$scope: myScope
});
}));
it('data is GG', function () {
expect(myScope.data).toEqual('GG');
});
});
When I try to run it, I receive a following error:
Error: [$injector:modulerr] Failed to instantiate module testApp due to:
Error: [$injector:unpr] Unknown provider: $routeProvider
But if I try to run again - I get this:
TypeError: 'undefined' is not an object (evaluating 'myScope.data')
Errors keep alternating if tests are run again. I'm using Visual Studio 2013 and Resharper 8 to run the Jasmine tests.
Add the angular-route bower component to your project and then inject the ngRoute into your module like this
var app = angular.module('testApp', ['ngRoute']);
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider.
when('/smth', {
templateUrl: 'smth.html',
controller: 'testController'
});
}]);
app.controller('testController', ['$scope', function ($scope) {
$scope.data = 'GG';
}]);
First make sure you have included angular-route.min.js.
This module has been separated from angularJs library, so you have will have to include it separately
then make sure you have added dependency for your module to ngRoute
e.g. angular.module('testApp', ['ngRoute']);
then in the test make sure you inject $route so its available in your tests as well
i have the below in my module config block:
var appModule = angular.module('myApp',['ngRoute'])
.config(['$httpProvider', '$routeProvider', '$locationProvider', '$translateProvider', function ($httpProvider, $routeProvider, $locationProvider, $translateProvider) {
$locationProvider.html5Mode(true)
$routeProvider
.when('/services/main', {templateUrl: '/services/main/html/main.html', controller: 'MainCtrl', resolve: {
myVar: function (varService) {
return varService.invokeService();
}
}})
}])
Spec File:
describe("Unit Testing: config - ", function() {
var appModule;
var routes;
beforeEach(function() {
appModule = angular.module("myApp");
});
it('should test routeProvider', function() {
inject(function($route, $location, $rootScope) {
routes = $route;
});
});
});
however, while running the test i am getting the below error:
Unit Testing: config - should test routeProvider FAILED
Error: [$injector:unpr] http://errors.angularjs.org/1.2.15/$injector/unpr?p0=%24routeProvider%20%3C-%20%24route
at Error (native)
my karma config includes the angular-route.min.js file. Any suggestions will be helpful.
The issue was resolved with use of angular.mock.module instead of angular.module.
appModule = angular.mock.module("myApp");
What i found that we should use mock to inject the module and it includes the configuration as well where as module is used to register a newly module. So if one is refering to the module already registered, we should use angular.mock.module.
The documentaion says:
This function registers a module configuration code. It collects the configuration information which will be used when the injector is created by inject.