I have some javascript and html files: User.js, index.html, Door.js
I want use any function in User.js file.
My user.js file
My door.js file
I call getUserInfo in user.Js from Door.js file in function
doorApplicationLoginPage.service
Error: [$injector:unpr] Unknown provider: UserServiceProvider <- UserService <- PerioMainController
var doorApplicationLoginPage = angular.module("PerioLoginPage", []);
doorApplicationLoginPage.service('UserService', function () {
this.getUserInfo = function () {
alert("getUserInfo");
}
this.reLoginUser = function () {
alert("reLoginUser");
}
});
var doorApplication = angular.module("PerioDoorApplication", []);
doorApplication.controller("PerioMainController", function ($scope, $http, $sce, UserService) {
UserService.getUserInfo();
});
Thank you.
You are injecting a service which is not referenced to your module.
See:
The UserService service is referenced in PerioLoginPage module
The PerioMainController controller is referenced in PerioDoorApplication module.
You've got either to:
reference the service in the same module as your controller.
inject the module where service is referenced to the module where controller is referenced.
In this case I can see you have two modules Periodicloginpage and periodicdoorapplication. So two services are defined in two modules. So you have to put the Periodicloginpage as dependency of periodicdoorapplication.
var doorApplication = angular.module("PerioDoorApplication", ["PerioLoginPage"]);
As I said in my comments you have two things to do at least:
You need to return the functions you want to use from the service (UserService):
return{
getUserInfo: getUserInfo,
reLoginUser: reLoginUser
};
Your module needs to reference the one the service is defined on:
angular.module('PerioDoorApplication', ['PerioLoginPage']);
And in your 'PerioMainController', a better way to write it would be:
doorApplication.controller('PerioMainController', ['$scope', '$http', '$sce', 'UserService',
function($scope, $http, $sce, UserService){
[...]
}
]);
Related
I'm trying to separate components into several files for a simple application but angular's dependency injector is giving me headaches and I don't really know what is expected.
Unknown provider: servicesProvider <- services <- maincontroller
Is the error I'm getting.
app.js
//Application definition with injected dependencies
var app = angular.module('leadcapacity', ['services', 'utils', 'customfilters', 'controllers']);
services.js
var services = angular.module('services', []);
services.service('xrmservice',
[
'$http', function($http) {
var oDataUrl = Xrm.Page.context.getClientUrl() + '/XRMServices/2011/OrganizationData.svc/';
var service = {};
service.query = function(entitySet, query) {
return $http.get(oDataUrl + entitySet + '?' + query);
};
return service;
}
]);
controllers.js
var ctrls = angular.module('controllers', ['utils', 'services']);
ctrls.controller('maincontroller',
function ($scope, services, utils) {
};
});
And the include order in index.html
<script src="service.js"></script>
<script src="controllers.js"></script>
<script src="app.js"></script>
Looks fine to me. I know this is perhaps not the best way to organize things, but getting a "Hello world" first would be nice.
Thanks.
Error message appearing in console clearly says that, services
dependency isn't exists in the module.
You have injected incorrect service name in maincontroller controller factory function, basically you were trying to to inject services(module name) instead of xrmservice(service name)
function ($scope, services, utils) {
should be
function ($scope, xrmservice, utils) {
Additional
Do follow Inline Array annotation of DI, as you were already used the same in your xrmservice service JS file, so that in future you don't need to go back and change that when you face javascript minification related issues.
Controller
ctrls.controller('maincontroller', [ '$scope', 'xrmservice', 'utils',
function ($scope, xrmservice, utils) {
//code goes here
//....
};
}]);
Although you have injected them into the module, you need to give them to the function so you can use the injected modules
ctrls.controller('maincontroller',
['$scope', 'services', 'utils', function ($scope, services, utils) {
};
}]);
As the title suggests I've recently started a new project where I'm using Browserify (and Gulp) to concatenate my Angular JS files (and the Angular sourcefile) into a single file - bundle.js.
I've decided to split my controllers, services and directives into separate files and then "require" them into my app.js file using Browserify like this:
(function () {
'use strict';
require('angular');
var tabCtrl = require('./controllers/tabs'),
dataService = require('./services/');
angular.module("citiToolsApp", [])
.service('dataService', ['$scope', dataService])
.controller('TabController', ['$scope', tabCtrl]);
}());
However when I try to access my service - dataService - from within my Tab Controller like this:
module.exports = function($scope, tabController) {
dataService.getPrograms(function (response) {
console.log(response.data);
});
};
I get an undefined error. I believe I need to pass dataService into the tabController but I'm unsure on the syntax to do this. Can anyone help with this?
Thanks
EDIT
I've also added the contents of my service file for further detail:
module.exports = function($http) {
this.getPrograms = function(callback) {
$http.get('/programs')
.then(callback);
};
};
I've realised my own mistake. I needed to pass in $http rather than $scope. So instead of:
(function () {
'use strict';
require('angular');
var tabCtrl = require('./controllers/tabs'),
dataService = require('./services/');
angular.module("citiToolsApp", [])
.service('dataService', ['$scope', dataService])
.controller('TabController', ['$scope', tabCtrl]);
}());
It should be:
(function () {
'use strict';
require('angular');
var tabCtrl = require('./controllers/tabs'),
dataService = require('./services/');
angular.module("citiToolsApp", [])
.service('dataService', ['$http', dataService])
.controller('TabController', ['$scope', tabCtrl]);
}());
There is something I don't fully understand with AngularJS. If I declare the controllers this way:
angular.module('ngApp', []).controller('AboutCtrl', ['$scope', function ($scope) {
$scope.awesomeThings = ['HTML5 Boilerplate', 'AngularJS', 'Karma'];
}]);
angular.module('ngApp', []).controller('ContactCtrl', ['$scope', function ($scope) {
$scope.awesomeThings = ['HTML5 Boilerplate', 'AngularJS', 'Karma'];
}]);
angular.module('ngApp', []).controller('MainCtrl', ['$scope', function ($scope) {
$scope.awesomeThings = ['HTML5 Boilerplate', 'AngularJS', 'Karma'];
}]);
...whenever I try to test them only one of them pass the test case(s):
describe('MainCtrl', function () {
var scope;
beforeEach(module('ngApp'));
beforeEach(inject(function ($rootScope, $controller) {
scope = $rootScope.$new();
$controller('MainCtrl', { $scope: scope });
}));
it('should attach a list of `awesomeThings` to the scope', function () {
expect(scope.awesomeThings.length).toBe(3);
});
});
(I have also three files with the same test case repeated, the only thing that changes is the controller name: AboutCtrl and ContactCtrl in the apprpriate locations).
On the other hand, if I say: var app = angular.module('ngApp', []); and then "attach" the controllers to it, everything works fine. The same if I attached them to the same chain in one angular.module('ngApp', []).controller(/* ... */).controller(/* ... */);
The reason I want them separate is because I want to have them in (three...N) different files.
Anyone has any clue?
You are re-declaring your ngApp module each time, rather than getting the already declared module.
From John Papa's Angular Style Guide:
•Only set once and get for all other instances.
Why?: A module should only be created once, then retrieved from that point and after.
/* recommended */
// to set a module
angular.module('app', []);
// to get a module
angular.module('app');
By calling angular.module('ngApp', []) you are creating a new module, not reusing the same one. In order to do that just call .module with the app name and no other argument
angular.module('ngApp')
file1.js
angular.module('ngApp').controller(...);
file2.js
angular.module('ngApp').controller(...);
you could also just save the module to a global variable and just use that variable
main.js
var app = angular.module('ngApp',[]);
file1.js
app.controller(...);
file2.js
app.controller(...);
I have a very simple controller that looks like this.
timeInOut.controller('timeInOutController', function($scope, $filter, $ionicScrollDelegate){
...
});
Whenever I try to create a unit test for it like so...
(function() {
'use strict';
var scope, controller, filter;
describe('timeInOutController', function () {
beforeEach(module('common.directives.kmDateToday'));
beforeEach(inject(function ($rootScope, $controller, $filter) {
scope = $rootScope.$new();
filter = $filter;
controller = $controller('timeInOutController', {
$scope: scope
});
}));
describe('#date setting', function(){
...
});
});
})();
I get the error:
[$injector:unpr] Unknown provider: $ionicScrollDelegateProvider <- $ionicScrollDelegate
Obviously in my example here I'm not trying to inject the $ionicScrollDelegate into the test, that's just because I've tried it any number of ways with no success and don't know which failed attempt to include.
Also in my karma.conf.js file I am including the ionic.bundle.js and angular-mocks.js libraries/files.
I can successfully unit test anything that doesn't use anything $ionic in it, so I know my testing framework is set up correctly, the issue is injecting anything ionic related.
You need to pass in all the parameters if you're going to instantiate your controller via angular. By adding the parameters you are telling angular that any time you create one of these controllers I need these things too because I am dependent upon them.
So my suggestion is to mock up some representation of these dependencies and inject them in when you are creating the controller. They do not have to be (and should not be) the actual services for your unit tests. Jasmine gives you the ability to create spy objects that you can inject so you can verify the the behavior of this unit.
(function() {
'use strict';
var scope, controller, filter, ionicScrollDelegate;
describe('timeInOutController', function () {
beforeEach(module('common.directives.kmDateToday'));
beforeEach(inject(function ($rootScope, $controller, $filter) {
scope = $rootScope.$new();
filter = $filter;
// func1 and func2 are functions that will be created as spies on ionicScrollDelegate
ionicScrollDelegate = jasmine.createSpyObj('ionicScrollDelegate', ['func1', 'func2']
controller = $controller('timeInOutController', {
$scope: scope,
$filter: filter,
$ionicScrollDelegate: ionicScrollDelegate
});
}));
describe('#date setting', function(){
...
});
});
})();
You can find more about spies via jasmine's documentation
You need to create mock objects for all dependencies your controller is using.
Take this controller as an example:
angular.module('app.module', [])
.controller('Ctrl', function($scope, $ionicLoading) {
$ionicLoading.show();
});
Here you are using the $ionicLoading service, so if you want to test this controller, you have to mock that object specifying the methods you're using in the controller:
describe('Test', function() {
// Mocks
var $scope, ionicLoadingMock;
var ctrl;
beforeEach(module('app.module'));
beforeEach(function() {
// Create $ionicLoading mock with `show` method
ionicLoadingMock = jasmine.createSpyObj('ionicLoading', ['show']);
inject(function($rootScope, $controller) {
$scope = $rootScope.$new();
ctrl = $controller('Ctrl', {
$scope: $scope,
$ionicLoading: ionicLoadingMock
});
});
});
// Your test goes here
it('should init controller for testing', function() {
expect(true).toBe(true);
});
});
I have a separate services module and I need a service injected into the config function of a dependent module.
angular.module('app', ['app.services'], function(myservice) {/*use myservice*/})
.controller('mycontroller', function($scope, myservice) {
$scope.message = myservice.sayHello();
});
angular.module('app.services', [], function($provide) {
$provide.service('myservice', function() {
return {sayHello: function() { return 'hello'; }};
});
});
I've also create a fiddle: http://jsfiddle.net/FzGmL/
The code will blow up with Unknown provider: myservice from app
If you remove the myservice argument from the app module config function, the mycontroller constructor function is able to have myservice injected just fine.
How can myservice be injected into the config function of the app module?
You're looking for the Module.run() method, It does initialization work for you after the injector is done loading.
angular.module('myApp', ['app.services'])
.run(function(myservice) {
//stuff here.
});